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

Manik Surtani msurtani at jboss.com
Thu Dec 14 12:18:48 EST 2006


  User: msurtani
  Date: 06/12/14 12:18:47

  Modified:    src/org/jboss/cache         TreeCacheProxyImpl.java
                        TransactionEntry.java TreeCache.java TreeNode.java
                        AbstractNode.java RegionManager.java NodeImpl.java
  Removed:     src/org/jboss/cache         ExtendedTreeCacheListener.java
  Log:
  The beginnings of porting JBCACHE-871 and JBCACHE-875 as well as rearranging the Node/Cache object model to something sensible
  
  Revision  Changes    Path
  1.54      +5 -0      JBossCache/src/org/jboss/cache/TreeCacheProxyImpl.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: TreeCacheProxyImpl.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/TreeCacheProxyImpl.java,v
  retrieving revision 1.53
  retrieving revision 1.54
  diff -u -b -r1.53 -r1.54
  --- TreeCacheProxyImpl.java	27 Nov 2006 17:07:05 -0000	1.53
  +++ TreeCacheProxyImpl.java	14 Dec 2006 17:18:47 -0000	1.54
  @@ -440,4 +440,9 @@
         return getRoot().getNodeSPI();
      }
   
  +   public void realRemove(Fqn f, boolean skipMarkerCheck)
  +   {
  +      treeCache.realRemove(f, skipMarkerCheck);
  +   }
  +
   }
  
  
  
  1.17      +163 -95   JBossCache/src/org/jboss/cache/TransactionEntry.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: TransactionEntry.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/TransactionEntry.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -b -r1.16 -r1.17
  --- TransactionEntry.java	8 Dec 2006 03:49:28 -0000	1.16
  +++ TransactionEntry.java	14 Dec 2006 17:18:47 -0000	1.17
  @@ -7,16 +7,21 @@
   package org.jboss.cache;
   
   
  +import org.apache.commons.logging.Log;
  +import org.apache.commons.logging.LogFactory;
  +import org.jboss.cache.config.Option;
   import org.jboss.cache.lock.IdentityLock;
   import org.jboss.cache.lock.NodeLock;
  -import org.jboss.cache.config.Option;
   import org.jboss.cache.marshall.MethodCall;
   
  -import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogFactory;
  -
   import javax.transaction.Transaction;
  -import java.util.*;
  +import java.util.ArrayList;
  +import java.util.Collection;
  +import java.util.Iterator;
  +import java.util.LinkedHashSet;
  +import java.util.LinkedList;
  +import java.util.List;
  +import java.util.ListIterator;
   
   /**
    * This is the value (key being the {@link GlobalTransaction}) in the transaction table
  @@ -32,22 +37,23 @@
    * </ul>
    *
    * @author <a href="mailto:bela at jboss.org">Bela Ban</a> Apr 14, 2003
  - * @version $Revision: 1.16 $
  + * @version $Revision: 1.17 $
    */
  -public class TransactionEntry {
  +public class TransactionEntry
  +{
   
      static Log log = LogFactory.getLog(TransactionEntry.class);
   
      /**
       * Local transaction
       */
  -   private Transaction ltx=null;
  +   private Transaction ltx = null;
      private Option option;
   
      /**
       * List<MethodCall> of modifications ({@link MethodCall}). They will be replicated on TX commit
       */
  -   private List<MethodCall> modification_list=new LinkedList<MethodCall>();
  +   private List<MethodCall> modification_list = new LinkedList<MethodCall>();
      private List<MethodCall> cl_mod_list = new LinkedList<MethodCall>();
   
      /**
  @@ -56,7 +62,7 @@
       * we have a corresponding entry in this list. A rollback will simply iterate over this list in
       * reverse to undo the modifications. Note that these undo-ops will never be replicated.
       */
  -   private List undo_list=new LinkedList();
  +   private List undo_list = new LinkedList();
   
      /**
       * LinkedHashSet<IdentityLock> of locks acquired by the transaction. We use
  @@ -73,29 +79,37 @@
      private List dummyNodesCreatedByCacheLoader;
   
      /**
  +    * List<Fqn> of nodes that have been removed by the transaction
  +    */
  +   private List<Fqn> removedNodes = new LinkedList<Fqn>();
  +
  +   /**
       * Constructs a new TransactionEntry.
       */
  -   public TransactionEntry() {
  +   public TransactionEntry()
  +   {
      }
   
      /**
       * Adds a modification to the modification list.
       */
  -   public void addModification(MethodCall m) {
  +   public void addModification(MethodCall m)
  +   {
         if (m == null) return;
         modification_list.add(m);
      }
   
       public void addCacheLoaderModification(MethodCall m)
       {
  -        if (m!=null) cl_mod_list.add(m);
  +      if (m != null) cl_mod_list.add(m);
       }
   
   
      /**
       * Returns all modifications.
       */
  -   public List<MethodCall> getModifications() {
  +   public List<MethodCall> getModifications()
  +   {
         return modification_list;
      }
   
  @@ -106,40 +120,67 @@
   
      /**
       * Adds an undo operation to the undo list.
  +    *
       * @see #undoOperations
       */
  -   public void addUndoOperation(MethodCall m) {
  +   public void addUndoOperation(MethodCall m)
  +   {
         undo_list.add(m);
      }
   
      /**
  +    * Adds the node that has been removed.
  +    *
  +    * @param fqn
  +    */
  +   public void addRemovedNode(Fqn fqn)
  +   {
  +      removedNodes.add(fqn);
  +   }
  +
  +   /**
  +    * Gets the list of removed nodes.
  +    */
  +   public List<Fqn> getRemovedNodes()
  +   {
  +      return new ArrayList(removedNodes);
  +   }
  +
  +
  +   /**
       * Returns the undo operations in use.
       * Note:  This list may be concurrently modified.
       */
  -   public List getUndoOperations() {
  +   public List getUndoOperations()
  +   {
         return undo_list;
      }
   
      /**
       * Sets the local transaction for this entry.
       */
  -   public void setTransaction(Transaction tx) {
  -      ltx=tx;
  +   public void setTransaction(Transaction tx)
  +   {
  +      ltx = tx;
      }
   
      /**
       * Returns a local transaction associated with this TransactionEntry
       */
  -   public Transaction getTransaction() {
  +   public Transaction getTransaction()
  +   {
         return ltx;
      }
   
      /**
       * Adds a lock to the end of the lock list, if it isn't already present.
       */
  -   public void addLock(NodeLock l) {
  -      if(l != null) {
  -         synchronized(locks) {
  +   public void addLock(NodeLock l)
  +   {
  +      if (l != null)
  +      {
  +         synchronized (locks)
  +         {
                locks.add(l);
            }
         }
  @@ -147,11 +188,15 @@
   
      /**
       * Add multiple locks to the lock list.
  +    *
       * @param newLocks Collection<IdentityLock>
       */
  -   public void addLocks(Collection newLocks) {
  -      if(newLocks != null) {
  -         synchronized(locks) {
  +   public void addLocks(Collection newLocks)
  +   {
  +      if (newLocks != null)
  +      {
  +         synchronized (locks)
  +         {
               locks.addAll(newLocks);
            }
         }
  @@ -162,8 +207,9 @@
       * 
       * @return a defensive copy of the internal data structure.
       */
  -   public List getLocks() {
  -      synchronized(locks)
  +   public List getLocks()
  +   {
  +      synchronized (locks)
         {
            return new ArrayList(locks);
         }
  @@ -171,11 +217,14 @@
   
      /**
       * Calls {@link #releaseAllLocksFIFO}.
  +    *
       * @deprecated don't think this is used anymore
       */
  -   public void releaseAllLocks(Object owner) {
  +   public void releaseAllLocks(Object owner)
  +   {
         releaseAllLocksFIFO(owner);
  -      synchronized (locks) {
  +      synchronized (locks)
  +      {
            locks.clear();
         }
      }
  @@ -184,13 +233,16 @@
       * Releases all locks held by the owner, in reverse order of creation.
       * Clears the list of locks held.
       */
  -   public void releaseAllLocksLIFO(Object owner) {
  +   public void releaseAllLocksLIFO(Object owner)
  +   {
   
  -      synchronized (locks) {
  +      synchronized (locks)
  +      {
            // Copying out to an array is faster than creating an ArrayList and iterating,
            // since list creation will just copy out to an array internally
            IdentityLock[] lockArray = (IdentityLock[]) locks.toArray(new IdentityLock[locks.size()]);
  -         for (int i = lockArray.length -1; i >= 0; i--) {
  +         for (int i = lockArray.length - 1; i >= 0; i--)
  +         {
                if (log.isTraceEnabled())
                {
                    log.trace("releasing lock for " + lockArray[i].getFqn() + " (" + lockArray[i] + ")");
  @@ -205,12 +257,15 @@
       * Releases all locks held by the owner, in order of creation.
       * Does not clear the list of locks held.
       */
  -   public void releaseAllLocksFIFO(Object owner) {
  +   public void releaseAllLocksFIFO(Object owner)
  +   {
         // I guess a copy would work as well
         // This seems fairly safe though
  -      synchronized (locks) {
  -         for (Iterator i = locks.iterator(); i.hasNext();) {
  -            IdentityLock lock = (IdentityLock)i.next();
  +      synchronized (locks)
  +      {
  +         for (Iterator i = locks.iterator(); i.hasNext();)
  +         {
  +            IdentityLock lock = (IdentityLock) i.next();
               lock.release(owner);
                if (log.isTraceEnabled())
                {
  @@ -223,27 +278,36 @@
      /**
       * Posts all undo operations to the TreeCache.
       */
  -   public void undoOperations(CacheSPI cache) {
  +   public void undoOperations(CacheSPI cache)
  +   {
         if (log.isTraceEnabled())
  +      {
            log.trace("undoOperations " + undo_list);
  +      }
         ArrayList l;
  -      synchronized (undo_list) {
  +      synchronized (undo_list)
  +      {
           l = new ArrayList(undo_list);
         }
  -      for (ListIterator i = l.listIterator(l.size()); i.hasPrevious();) {
  -         MethodCall undo_op = (MethodCall)i.previous();
  +      for (ListIterator i = l.listIterator(l.size()); i.hasPrevious();)
  +      {
  +         MethodCall undo_op = (MethodCall) i.previous();
            undo(undo_op, cache);
         }
      }
   
  -   private void undo(MethodCall undo_op, CacheSPI cache) {
  -      try {
  -          Object retval = undo_op.invoke(((TreeCacheProxyImpl)cache).getTreeCache());
  +   private void undo(MethodCall undo_op, CacheSPI cache)
  +   {
  +      try
  +      {
  +         Object retval = undo_op.invoke(((TreeCacheProxyImpl) cache).getTreeCache());
             if (retval instanceof Throwable)
             {
  -              throw (Throwable) retval;
  +            throw(Throwable) retval;
  +         }
             }
  -      } catch (Throwable t) {
  +      catch (Throwable t)
  +      {
            log.error("undo operation failed, error=" + t);
            log.trace(t, t);
         }
  @@ -252,13 +316,16 @@
      /**
       * Returns debug information about this transaction.
       */
  -   public String toString() {
  -      StringBuffer sb=new StringBuffer();
  +   public String toString()
  +   {
  +      StringBuffer sb = new StringBuffer();
         sb.append("\nmodification_list: ").append(modification_list);
  -      synchronized (undo_list) {
  +      synchronized (undo_list)
  +      {
            sb.append("\nundo_list: ").append(undo_list);
         }
  -      synchronized (locks) {
  +      synchronized (locks)
  +      {
            sb.append("\nlocks: ").append(locks);
         }
         return sb.toString();
  @@ -277,6 +344,7 @@
   
       /**
        * Sets a transaction-scope option override
  +    *
        * @param o
        */
       public void setOption(Option o)
  
  
  
  1.292     +195 -141  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.291
  retrieving revision 1.292
  diff -u -b -r1.291 -r1.292
  --- TreeCache.java	8 Dec 2006 18:49:17 -0000	1.291
  +++ TreeCache.java	14 Dec 2006 17:18:47 -0000	1.292
  @@ -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.291 2006/12/08 18:49:17 genman Exp $
  + * @version $Id: TreeCache.java,v 1.292 2006/12/14 17:18:47 msurtani Exp $
    *          <p/>
    * @see <a href="http://labs.jboss.com/portal/jbosscache/docs">JBossCache doc</a>
    */
  @@ -110,6 +110,7 @@
       * Root DataNode.
       */
      protected DataNode root;
  +
      {
         this.rootSpi = new TreeCacheProxyImpl(this);
         this.root = NodeFactory.getInstance().createRootDataNode(NodeFactory.NODE_TYPE_TREENODE, this.rootSpi);
  @@ -548,8 +549,10 @@
            // Yes -- cache is configured LOCAL but app doesn't know it -- Brian
            //throw new IllegalArgumentException("Cannot fetch partial state, targets are " + sources + " and stateId is " + stateId);
            if (log.isWarnEnabled())
  +         {
               log.warn("Cannot fetch partial state, targets are " + Arrays.asList(sources) + 
                     " and stateId is " + stateId);
  +         }
            return;
         }
   
  @@ -634,7 +637,7 @@
            initialiseCacheLoaderManager();
         }
   
  -      getRegionManager(); // make sure we create one
  +      getRegionManager();// make sure we create one
         createEvictionPolicy();
   
         switch (configuration.getCacheMode())
  @@ -648,7 +651,7 @@
            case INVALIDATION_SYNC:
               if (log.isDebugEnabled()) log.debug("cache mode is " + configuration.getCacheMode());
               if (channel != null)
  -            { // already started
  +            {// already started
                  log.info("channel is already running");
                  return;
               }
  @@ -657,7 +660,7 @@
               channel = getMultiplexerChannel();
   
               if (channel != null)
  -            { // mux channel
  +            {// mux channel
                  if (log.isDebugEnabled())
                  {
                     log.debug("Created Multiplexer Channel for cache cluster " + configuration.getClusterName() +
  @@ -681,14 +684,14 @@
               channel.setOpt(Channel.AUTO_GETSTATE, true);
               channel.setOpt(Channel.BLOCK, true);
   
  -/* Used for JMX jconsole for JDK5.0
  +            /* Used for JMX jconsole for JDK5.0
               ArrayList servers=MBeanServerFactory.findMBeanServer(null);
               if(servers == null || servers.size() == 0) {
                   throw new Exception("No MBeanServers found;" +
                                       "\nJmxTest needs to be run with an MBeanServer present, or inside JDK 5"); }
               MBeanServer server=(MBeanServer)servers.get(0);
               JmxConfigurator.registerChannel(channel, server, "JGroups:channel=" + channel.getChannelName() , true);
  -*/
  +            */
               // disp = new InactiveRegionAwareRpcDispatcher(channel, ml, this, this);
               disp = new RpcDispatcher(channel, ml, this, this);
               disp.setMarshaller(getMarshaller());
  @@ -790,7 +793,9 @@
   
         // start any eviction threads.
         if (regionManager.isUsingEvictions())
  +      {
   		  regionManager.startEvictionThread();
  +      }
   
         notifier.notifyCacheStarted(getCacheSPI());
         started = true;
  @@ -950,7 +955,9 @@
      public Address getCoordinator()
      {
         if (channel == null)
  +      {
            return null;
  +      }
   
         synchronized (members)
         {
  @@ -1074,7 +1081,7 @@
   
         if (!exists(subtree))
         {
  -         return;   // node does not exist. Maybe it has been recursively removed.
  +         return;// node does not exist. Maybe it has been recursively removed.
         }
   
         if (log.isTraceEnabled())
  @@ -1096,7 +1103,7 @@
                       tmp,
                       false,   // no undo ops
                       false,   // no nodeEvent
  -                    true);   // is an eviction
  +                    true);// is an eviction
            }
         }
   
  @@ -1260,7 +1267,7 @@
       */
      public Map _getData(Fqn fqn)
      {
  -      DataNode n = findNode(fqn);
  +      Node n = findNode(fqn);
         if (n == null) return null;
         return n.getNodeSPI().getRawData();
      }
  @@ -1293,7 +1300,7 @@
   
      public Set _getKeys(Fqn fqn) throws CacheException
      {
  -      DataNode n = findNode(fqn);
  +      Node n = findNode(fqn);
         if (n == null)
         {
            return null;
  @@ -1340,7 +1347,7 @@
                    append(sendNodeEvent).append("\")"));
         }
         if (sendNodeEvent) notifier.notifyNodeVisited(fqn, true);
  -      DataNode n = findNode(fqn);
  +      Node n = findNode(fqn);
         if (n == null)
   	  {
   		 log.trace("node not found");
  @@ -1378,7 +1385,7 @@
       */
      public Node peek(Fqn fqn)
      {
  -      return findInternal(fqn);
  +      return findInternal(fqn, true);
      }
   
      /**
  @@ -1407,7 +1414,7 @@
       */
      public boolean exists(Fqn fqn)
      {
  -      Node n = findInternal(fqn);
  +      Node n = findInternal(fqn, false);
         return n != null;
      }
   
  @@ -1416,7 +1423,7 @@
       *
       * @param fqn
       */
  -   private Node findInternal(Fqn fqn)
  +   private Node findInternal(Fqn fqn, boolean includeNodesMarkedAsRemoved)
      {
         if (fqn == null || fqn.size() == 0) return root;
         Node n = root;
  @@ -1429,8 +1436,12 @@
            {
               return null;
            }
  +         else if (!includeNodesMarkedAsRemoved && ((DataNode) n).isDeleted())
  +         {
  +            return null;
         }
  -      return (DataNode) n;
  +      }
  +      return n;
      }
   
   
  @@ -1454,7 +1465,7 @@
       */
      public boolean exists(Fqn fqn, Object key)
      {
  -      Node n = findInternal(fqn);
  +      Node n = findInternal(fqn, false);
         if (n == null)
         {
            return false;
  @@ -1620,9 +1631,9 @@
       * @throws CacheException If node doesn't exist, a NodeNotExistsException is throw. Other exceptions are
       * LockingException, TimeoutException and UpgradeException
       */
  -//   public void lock(Fqn fqn, Object owner, int lock_type, boolean lock_recursive) throws CacheException {
  -//
  -//   }
  +   //   public void lock(Fqn fqn, Object owner, int lock_type, boolean lock_recursive) throws CacheException {
  +   //
  +   //   }
   
      /**
       * Unlock a given node (or the entire subtree starting at this node)
  @@ -1632,9 +1643,9 @@
       * @param unlock_recursive If true, the entire subtree is unlocked, else only the given node
       * @param force Release the lock even if we're not the owner
       */
  -//   public void unlock(Fqn fqn, Object owner, boolean unlock_recursive, boolean force) {
  -//
  -//   }
  +   //   public void unlock(Fqn fqn, Object owner, boolean unlock_recursive, boolean force) {
  +   //
  +   //   }
   
      /**
       * Releases all locks for this node and the entire node subtree.
  @@ -1728,7 +1739,7 @@
   
      public Set _getChildrenNames(Fqn fqn) throws CacheException
      {
  -      DataNode n = findNode(fqn);
  +      Node n = findNode(fqn);
         if (n == null) return null;
         Set s = n.getChildrenNames();
         return s;
  @@ -1859,7 +1870,7 @@
         {
            return 0;
         }
  -      int count = 1; // for n
  +      int count = 1;// for n
         for (Node child : n.getNodeSPI().getChildrenMap().values())
         {
            count += numNodes(child);
  @@ -1886,7 +1897,7 @@
       */
      public int getNumberOfAttributes(Fqn fqn)
      {
  -      DataNode n = findNode(fqn);
  +      Node n = findNode(fqn);
         return numAttributes(n);
      }
   
  @@ -1990,7 +2001,7 @@
   
         if (mode == GroupRequest.GET_NONE)
         {
  -         return new ArrayList(); // async case
  +         return new ArrayList();// async case
         }
   
         if (log.isTraceEnabled())
  @@ -2101,6 +2112,7 @@
         Method method = getClass().getDeclaredMethod(method_name, types);
         return callRemoteMethods(members, method, args, synchronous, exclude_self, timeout);
      }
  +
      /* -------------------- End Remote method calls ------------------ */
   
      /* --------------------- Callbacks -------------------------- */
  @@ -2224,7 +2236,7 @@
            tx_table.addUndoOperation(tx, undo_op);
         }
   
  -      ((DataNode)n).put(data, (boolean)erase_contents);
  +      ((DataNode) n).put(data, (boolean) erase_contents);
   
         notifier.notifyNodeModified(fqn, false, rawData);
   
  @@ -2261,7 +2273,7 @@
   		  log.warn("using a map as a key in a map, did you mean to do that?");
   	  }
   
  -      DataNode n = findNodeCheck(tx, fqn);
  +      Node n = findNodeCheck(tx, fqn);
         Map rawData = n.getNodeSPI().getRawData();
         notifier.notifyNodeModified(fqn, true, rawData);
   
  @@ -2342,7 +2354,7 @@
              throws CacheException
      {
   
  -      DataNode n;
  +      Node n;
         Node parent_node;
         MethodCall undo_op = null;
   
  @@ -2351,6 +2363,26 @@
            log.trace("_remove(" + tx + ", \"" + fqn + "\", undo=" + create_undo_ops + ")");
         }
   
  +      // check if this is triggered by a rollback operation ...
  +      if (tx != null)
  +      {
  +         try
  +         {
  +            int status = getTransactionManager().getTransaction().getStatus();
  +            if (status == Status.STATUS_MARKED_ROLLBACK || status == Status.STATUS_ROLLEDBACK || status == Status.STATUS_ROLLING_BACK)
  +            {
  +               log.debug("This remove call is triggered by a transaction rollback, as a compensation operation.  Do a realRemove() instead.");
  +               realRemove(fqn, true);
  +               return;
  +            }
  +         }
  +         catch (Exception e)
  +         {
  +            // what do we do here?
  +            log.trace("Caught exception dealing with transaction manager", e);
  +         }
  +      }
  +
         if (fqn.size() == 0)
         {
            Set children = getChildrenNames(fqn);
  @@ -2398,20 +2430,28 @@
         parent_node = n.getParent();
   
         // remove subtree from parent
  -      parent_node.getNodeSPI().getChildrenMap().remove(n.getName());
  +      if (eviction || configuration.isNodeLockingOptimistic())
  +      {
  +         parent_node.getNodeSPI().getChildrenMap().remove(n.getFqn().getLast());
  +      }
  +      else
  +      {
  +         ((DataNode) n).markAsDeleted(true);
  +      }
  +
         if (eviction)
         {
            parent_node.getNodeSPI().setChildrenLoaded(false);
         }
   
         // release all locks for the entire subtree
  -      n.getNodeSPI().getLock().releaseAll(tx != null ? tx : (Object) Thread.currentThread());
  +      // n.getNodeSPI().getLock().releaseAll(tx != null ? tx : (Object) Thread.currentThread());
   
         // create a compensating method call (reverting the effect of
         // this modification) and put it into the TX's undo list.
         if (tx != null && create_undo_ops && !eviction)
         {
  -         undo_op = MethodCallFactory.create(MethodDeclarations.addChildMethodLocal, tx, parent_node.getFqn(), n.getName(), n, false);
  +         undo_op = MethodCallFactory.create(MethodDeclarations.addChildMethodLocal, tx, parent_node.getFqn(), n.getFqn().getLast(), n, false);
   
            // 1. put undo-op in TX' undo-operations list (needed to rollback TX)
            tx_table.addUndoOperation(tx, undo_op);
  @@ -2450,7 +2490,7 @@
      public Object _remove(GlobalTransaction tx, Fqn fqn, Object key, boolean create_undo_ops)
              throws CacheException
      {
  -      DataNode n = null;
  +      Node n = null;
         MethodCall undo_op = null;
         Object old_value = null;
   
  @@ -2529,7 +2569,7 @@
      public void _removeData(GlobalTransaction tx, Fqn fqn, boolean create_undo_ops, boolean sendNodeEvent, boolean eviction, DataVersion version)
              throws CacheException
      {
  -      DataNode n = null;
  +      Node n = null;
         MethodCall undo_op = null;
   
         if (log.isTraceEnabled())
  @@ -2579,7 +2619,7 @@
            notifier.notifyNodeVisited(fqn, false);
         }
         else
  -      { // FIXME Bela did this so GUI view can refresh the view after node is evicted. But this breaks eviction policy, especially AOP!!!!
  +      {// FIXME Bela did this so GUI view can refresh the view after node is evicted. But this breaks eviction policy, especially AOP!!!!
            if (eviction)
            {
               notifier.notifyNodeEvicted(fqn, false);
  @@ -2606,7 +2646,7 @@
       */
      public void _evict(Fqn fqn) throws CacheException
      {
  -      if (!exists(fqn)) return;   // node does not exist. Maybe it has been recursively removed.
  +      if (!exists(fqn)) return;// node does not exist. Maybe it has been recursively removed.
         // use remove method now if there is a child node. Otherwise, it is removed
         boolean create_undo_ops = false;
         boolean sendNodeEvent = false;
  @@ -2634,7 +2674,7 @@
       */
      public void _evict(Fqn fqn, DataVersion version) throws CacheException
      {
  -      if (!exists(fqn)) return;  // node does not exist
  +      if (!exists(fqn)) return;// node does not exist
   
         boolean create_undo_ops = false;
         boolean sendNodeEvent = false;
  @@ -2659,13 +2699,13 @@
       * @param key
       * @throws CacheException
       */
  -//    public void _evict(Fqn fqn, Object key) throws CacheException {
  -//       if(!exists(fqn)) return;
  -//       boolean create_undo_ops = false;
  -//       boolean sendNodeEvent = false;
  -//       boolean eviction=true;
  -//       _removeData(null, fqn, create_undo_ops, sendNodeEvent, eviction);
  -//    }
  +   //    public void _evict(Fqn fqn, Object key) throws CacheException {
  +   //       if(!exists(fqn)) return;
  +   //       boolean create_undo_ops = false;
  +   //       boolean sendNodeEvent = false;
  +   //       boolean eviction=true;
  +   //       _removeData(null, fqn, create_undo_ops, sendNodeEvent, eviction);
  +   //    }
   
   
      /**
  @@ -2676,7 +2716,7 @@
      {
         if (log.isTraceEnabled())
         {
  -         log.trace("_addChild(\"" + parent_fqn +"\", \"" + child_name + "\", node=" + childNode + ")");
  +         log.trace("_addChild(\"" + parent_fqn + "\", \"" + child_name + "\", node=" + childNode + ")");
         }
   
         if (parent_fqn == null || child_name == null || childNode == null)
  @@ -2684,8 +2724,8 @@
            log.error("parent_fqn or child_name or childNode was null");
            return;
         }
  -      DataNode tmp = findNode(parent_fqn);
  -      if (tmp == null)
  +      DataNode parentNode = (DataNode) findNode(parent_fqn);
  +      if (parentNode == null)
         {
            log.warn("node " + parent_fqn + " not found");
            return;
  @@ -2693,7 +2733,9 @@
   
         Fqn fqn = new Fqn(parent_fqn, child_name);
         notifier.notifyNodeCreated(fqn, true);
  -      tmp.addChild(child_name, childNode);
  +      parentNode.addChild(child_name, childNode);
  +
  +      childNode.markAsDeleted(false, true);
   
         if (gtx != null && undoOps)
         {
  @@ -2820,11 +2862,11 @@
   
         // for now, perform a very simple series of getData calls.
   
  -      DataNode actualNode = findNode(fqn);
  +      Node actualNode = findNode(fqn);
         Fqn backupNodeFqn = null;
         if (actualNode == null && searchSubtrees)
         {
  -         DataNode backupSubtree = findNode(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN);
  +         Node backupSubtree = findNode(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN);
            if (backupSubtree != null)
            {
               Map children = backupSubtree.getNodeSPI().getChildrenMap();
  @@ -2878,7 +2920,7 @@
         NodeData data = new NodeData(BuddyManager.getActualFqn(node.getFqn()), node.getData());
         list.add(data);
         Map<Object, Node> children = node.getNodeSPI().getChildrenMap();
  -      for (Node childNode: children.values())
  +      for (Node childNode : children.values())
         {
            getNodeData(list, childNode);
         }
  @@ -2960,7 +3002,7 @@
       */
      public void _releaseAllLocks(Fqn fqn)
      {
  -      DataNode n;
  +      Node n;
   
         try
         {
  @@ -2996,7 +3038,7 @@
      {
         try
         {
  -         DataNode n = findNode(fqn);
  +         Node n = findNode(fqn);
            if (n == null) return null;
            return n.toString();
         }
  @@ -3182,13 +3224,13 @@
   
      private void moveFqns(Node node, Fqn newBase)
      {
  -      Fqn newFqn = new Fqn(newBase, ((TreeNode)node).getName());
  +      Fqn newFqn = new Fqn(newBase, ((TreeNode) node).getName());
         node.getNodeSPI().setFqn(newFqn);
      }
   
      class MessageListenerAdaptor implements ExtendedMessageListener
      {
  -      final Log my_log;   // Need this to run under jdk1.3
  +      final Log my_log;// Need this to run under jdk1.3
         final boolean trace;
   
         /**
  @@ -3245,13 +3287,13 @@
         {
            try
            {
  -//            // We use the lock acquisition timeout rather than the
  -//            // state transfer timeout, otherwise we'd never try
  -//            // to break locks before the requesting node gives up
  -//            return cache._getState(Fqn.fromString(SEPARATOR),
  -//               cache.getLockAcquisitionTimeout(),
  -//               true,
  -//               true);
  +            //            // We use the lock acquisition timeout rather than the
  +            //            // state transfer timeout, otherwise we'd never try
  +            //            // to break locks before the requesting node gives up
  +            //            return cache._getState(Fqn.fromString(SEPARATOR),
  +            //               cache.getLockAcquisitionTimeout(),
  +            //               true,
  +            //               true);
               // Until flush is in place, use the old mechanism
               // where we wait the full state retrieval timeout
               return _getState(Fqn.ROOT, configuration.getInitialStateRetrievalTimeout(), true, true);
  @@ -3565,8 +3607,6 @@
   
      /**
       * Indicates that a channel has received a BLOCK event from FLUSH protocol.
  -    * 
  -    * 
       */
      public void block()
      {
  @@ -3643,12 +3683,12 @@
         Transaction tx;
   
         if ((tx = getLocalTransaction()) == null)
  -      { // no transaction is associated with the current thread
  +      {// no transaction is associated with the current thread
            return null;
         }
   
         if (!isValid(tx))
  -      { // we got a non-null transaction, but it is not active anymore
  +      {// we got a non-null transaction, but it is not active anymore
            int status = -1;
            try
            {
  @@ -3717,7 +3757,7 @@
         {
            if (t instanceof CacheException)
            {
  -            throw (CacheException) t;
  +            throw(CacheException) t;
            }
            throw new RuntimeException(t);
         }
  @@ -3744,7 +3784,7 @@
       * nodes have to be added to the transaction's {@link TransactionEntry}
       * field.<br>
       * When a lock is acquired on a node, a reference to the lock has to be 
  -    * {@link TransactionEntry#addLock(IdentityLock) added to the list of locked nodes} 
  +    * {@link TransactionEntry#addLock(org.jboss.cache.lock.NodeLock) added to the list of locked nodes}
       * in the {@link TransactionEntry}.
       * <p>This operation will also apply different locking to the tree nodes, depending on
       * <tt>operation_type</tt>. If it is <tt>read</tt> type, all nodes will be acquired with
  @@ -3754,7 +3794,7 @@
       * @param fqn Fully qualified name for the corresponding node.
       * @return DataNode
       */
  -   public DataNode findNode(Fqn fqn)
  +   public Node findNode(Fqn fqn)
      {
         try
         {
  @@ -3767,9 +3807,9 @@
         }
      }
   
  -   private DataNode findNodeCheck(GlobalTransaction tx, Fqn fqn)
  +   private Node findNodeCheck(GlobalTransaction tx, Fqn fqn)
      {
  -	  DataNode n = findNode(fqn);
  +      Node n = findNode(fqn);
         if (n == null)
         {
            String errStr = "node " + fqn + " not found (gtx=" + tx + ", caller=" + Thread.currentThread() + ")";
  @@ -3783,36 +3823,49 @@
      }
   
      /**
  -    * Finds a node given a fully qualified name and DataVersion.
  +    * Internal method; not to be used externally.
  +    *
  +    * @param f
       */
  -   private DataNode findNode(Fqn fqn, DataVersion version) throws CacheException
  +   public void realRemove(Fqn f, boolean skipMarkerCheck)
      {
  -      Node n, child_node = null;
  -      Object child_name;
  -
  -      if (fqn == null) return null;
  -      DataNode toReturn = null;
  -      if (fqn.isRoot())
  +      DataNode n = (DataNode) findInternal(f, true);
  +      if (n == null)
         {
  -         toReturn = root;
  +         return;
         }
  -      else
  +
  +      if (log.isDebugEnabled()) log.debug("Performing a real remove for node " + f + ", marked for removal.");
  +      if (skipMarkerCheck || n.isDeleted())
         {
  -         n = root;
  -         int size = fqn.size();
  -         for (int i = 0; i < size; i++)
  +         if (n.getFqn().isRoot())
            {
  -            child_name = fqn.get(i);
  -            child_node = n.getNodeSPI().getChildrenMap().get(child_name);
  -            if (child_node == null)
  +            // do not actually delete; just remove deletion marker
  +            n.markAsDeleted(false);
  +            // but now remove all children, since the call has been to remove("/")
  +            n.removeChildren();
  +         }
  +         else
               {
  -               return null;
  +            getInvocationContext().getOptionOverrides().setBypassInterceptorChain(true);
  +            n.getParent().removeChild(n.getFqn());
               }
  -            n = child_node;
            }
  -         toReturn = (DataNode) child_node;
  +      else
  +      {
  +         if (log.isDebugEnabled()) log.debug("Node " + f + " NOT marked for removal as expected, not removing!");
  +      }
         }
   
  +   /**
  +    * Finds a node given a fully qualified name and DataVersion.
  +    */
  +   private Node findNode(Fqn fqn, DataVersion version) throws CacheException
  +   {
  +      if (fqn == null) return null;
  +
  +      Node toReturn = findInternal(fqn, false);
  +
         if (version != null)
         {
            // we need to check the version of the data node...
  @@ -3826,7 +3879,6 @@
               // we have a versioning problem; throw an exception!
               throw new CacheException("Unable to validate versions.");
            }
  -
         }
         return toReturn;
      }
  @@ -3834,7 +3886,9 @@
      public synchronized RegionManager getRegionManager()
      {
         if (regionManager == null)
  +      {
            regionManager = new RegionManager(this);
  +      }
         return regionManager;
      }
   
  
  
  
  1.30      +63 -45    JBossCache/src/org/jboss/cache/TreeNode.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: TreeNode.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/TreeNode.java,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -b -r1.29 -r1.30
  --- TreeNode.java	8 Dec 2006 19:03:56 -0000	1.29
  +++ TreeNode.java	14 Dec 2006 17:18:47 -0000	1.30
  @@ -13,20 +13,20 @@
    * hashmap of general data.  If the node is created in a replicated cache, the
    * relative and fully qualified name, and the keys and values of the hashmap
    * must be serializable.
  - * <p>
  + * <p/>
    * The current version supports different levels of transaction locking such as
    * simple locking ({@link org.jboss.cache.lock.IsolationLevel#SERIALIZABLE}, or Read/Write lock with
    * upgrade ( {@link org.jboss.cache.lock.IsolationLevel#REPEATABLE_READ}) --that is the read lock will be
    * automatically upgraded to write lock when the same owner intends to modify
    * the data after read.
  - * <p>
  + * <p/>
    * Implementations may not necessarily be <em>not</em> synchronized, so access
    * to instances of  need to be run under an isolation level above NONE.
    *
    * @author Bela Ban March 25 2003
    * @author Ben Wang
    * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
  - * @version $Revision: 1.29 $
  + * @version $Revision: 1.30 $
    */
   
   public interface TreeNode extends Node
  @@ -45,6 +45,7 @@
       /**
        * Puts the contents of a map into this node.
        * Optionally erases the existing contents.
  +    *
        * @param eraseData true to erase the existing contents
        */
       void put(Map data, boolean eraseData);
  @@ -75,4 +76,21 @@
        */
       void addChild(Object child_name, Node n);
   
  +   /**
  +    * Tests whether a node has been marked as deleted.
  +    */
  +   public boolean isDeleted();
  +
  +   /**
  +    * Sets the deletion marker on the node (but not on children)
  +    *
  +    * @param isDeleted
  +    */
  +   public void markAsDeleted(boolean isDeleted);
  +
  +   /**
  +    * Sets the deletion marker on the node, with the option to set this on children as well.
  +    */
  +   public void markAsDeleted(boolean isDeleted, boolean recursive);
  +
   }
  
  
  
  1.23      +27 -1     JBossCache/src/org/jboss/cache/AbstractNode.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: AbstractNode.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/AbstractNode.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -b -r1.22 -r1.23
  --- AbstractNode.java	20 Nov 2006 03:53:53 -0000	1.22
  +++ AbstractNode.java	14 Dec 2006 17:18:47 -0000	1.23
  @@ -3,6 +3,8 @@
    */
   package org.jboss.cache;
   
  +import java.util.Map;
  +
   /**
    * Base class for {@link NodeImpl}.
    *
  @@ -10,4 +12,28 @@
    */
   public abstract class AbstractNode implements DataNode, NodeSPI
   {
  +   protected boolean deleted;
  +   protected Map<Object, AbstractNode> children;
  +
  +   public boolean isDeleted()
  +   {
  +      return deleted;
  +   }
  +
  +   public void markAsDeleted(boolean marker)
  +   {
  +      markAsDeleted(marker, false);
  +   }
  +
  +   public void markAsDeleted(boolean marker, boolean recursive)
  +   {
  +      deleted = marker;
  +      if (recursive && children != null)
  +      {
  +         for (AbstractNode child : children.values())
  +         {
  +            child.markAsDeleted(marker, true);
  +         }
  +      }
  +   }
   }
  
  
  
  1.16      +24 -7     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.15
  retrieving revision 1.16
  diff -u -b -r1.15 -r1.16
  --- RegionManager.java	27 Nov 2006 04:49:46 -0000	1.15
  +++ RegionManager.java	14 Dec 2006 17:18:47 -0000	1.16
  @@ -136,8 +136,10 @@
            // 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;
  @@ -262,9 +264,11 @@
                  r.setActive(true);
                  // FIXME - persistent state transfer counts too!
                  if (treeCache.getConfiguration().isFetchInMemoryState())
  +               {
                     activateRegion(r.getFqn().toString());
               }
            }
  +         }
            else if (defaultInactive)
            {
               // "Active" region is not the default, so create a region
  @@ -272,9 +276,11 @@
               r.setActive(true);
               // FIXME - persistent state transfer counts too!
               if (treeCache.getConfiguration().isFetchInMemoryState())
  +            {
                  activateRegion(r.getFqn().toString());
            }
         }
  +      }
         catch (Exception e)
         {
            throw new RuntimeException(e);
  @@ -302,7 +308,7 @@
         Fqn fqn = Fqn.fromString(subtreeFqn);
   
         // Check whether the node already exists and has data
  -      DataNode subtreeRoot = treeCache.findNode(fqn);
  +      Node subtreeRoot = treeCache.findNode(fqn);
   
         /*
          * Commented out on Nov 16,2006 Manik&Vladimir 
  @@ -355,8 +361,10 @@
               if (groupMembers.length < 2)
               {
                  if (log.isDebugEnabled())
  +               {
                     log.debug("No nodes able to give state");
               }
  +            }
               else
               {
                  treeCache.fetchPartialState(groupMembers, subtreeRoot.getFqn());
  @@ -431,7 +439,7 @@
       *                                     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>
  +    * @throws IllegalStateException       if {@link org.jboss.cache.config.Configuration#isUseRegionBasedMarshalling()} is <code>false</code>
       */
      public void inactivateRegion(String subtreeFqn) throws CacheException
      {
  @@ -623,9 +631,11 @@
                  // FIXME - we should always clean up; otherwise stale data 
                  // is in memory!
                  if (treeCache.getConfiguration().isFetchInMemoryState())
  +               {
                     inactivateRegion(fqn.toString());
               }
            }
  +         }
            else if (!defaultInactive)
            {
               region = getRegion(fqn, true);
  @@ -633,9 +643,11 @@
               // FIXME - we should always clean up; otherwise stale data 
               // is in memory!
               if (treeCache.getConfiguration().isFetchInMemoryState())
  +            {
                  inactivateRegion(fqn.toString());
            }
         }
  +      }
         catch (Exception e)
         {
            throw new RuntimeException(e);
  @@ -687,7 +699,9 @@
         List<Region> regions = new ArrayList<Region>();
   
         for (Region r : regionsRegistry.values())
  +      {
            if (r.getEvictionPolicy() != null && evictionTimerTask.isRegionRegisteredForProcessing(r)) regions.add(r);
  +      }
   
         Collections.sort(regions);
   
  @@ -726,7 +740,9 @@
            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;
  @@ -755,7 +771,8 @@
         return sb.toString();
      }
      
  -   public String toString() {
  +   public String toString()
  +   {
         return "RegionManager " + dumpRegions();
      }
   }
  @@ -774,7 +791,7 @@
    * @author Ben Wang 02-2004
    * @author Daniel Huang (dhuang at jboss.org)
    * @author Brian Stansberry
  - * @version $Id: RegionManager.java,v 1.15 2006/11/27 04:49:46 genman Exp $
  + * @version $Id: RegionManager.java,v 1.16 2006/12/14 17:18:47 msurtani Exp $
    */
   /*public class ERegionManager
   {
  
  
  
  1.25      +42 -15    JBossCache/src/org/jboss/cache/NodeImpl.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: NodeImpl.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/NodeImpl.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -b -r1.24 -r1.25
  --- NodeImpl.java	12 Dec 2006 15:08:05 -0000	1.24
  +++ NodeImpl.java	14 Dec 2006 17:18:47 -0000	1.25
  @@ -31,7 +31,7 @@
   /**
    * Basic data node class.
    */
  -public class NodeImpl implements DataNode, Node, NodeSPI, Serializable
  +public class NodeImpl extends AbstractNode implements Node, Serializable
   {
   
      private static final long serialVersionUID = -8200950905894940931L;
  @@ -73,11 +73,6 @@
      private Fqn fqn;
   
      /**
  -    * Map of children names to children.
  -    */
  -   private Map<Object, Node> children;
  -
  -   /**
       * Map of general data keys to values.
       */
      private Map data;
  @@ -180,12 +175,12 @@
         {
            if (getFqn().isRoot())
            {
  -            children = new ConcurrentHashMap<Object, Node>(64, .5f, 16);
  +            children = new ConcurrentHashMap<Object, AbstractNode>(64, .5f, 16);
            }
            else
            {
               // Less segments to save memory
  -            children = new ConcurrentHashMap<Object, Node>(4, .75f, 4);
  +            children = new ConcurrentHashMap<Object, AbstractNode>(4, .75f, 4);
            }
         }
         return children;
  @@ -343,19 +338,20 @@
   
      private Node getOrCreateChild(Object child_name, GlobalTransaction gtx, boolean createIfNotExists)
      {
  -      DataNode child;
  +
  +      NodeImpl child;
         if (child_name == null)
         {
            throw new IllegalArgumentException("null child name");
         }
   
  -      child = (DataNode) children().get(child_name);
  +      child = (NodeImpl) children().get(child_name);
         if (createIfNotExists && child == null)
         {
            // construct the new child outside the synchronized block to avoid
            // spending any more time than necessary in the synchronized section
            Fqn child_fqn = new Fqn(this.fqn, child_name);
  -         DataNode newChild = (DataNode) NodeFactory.getInstance().createNode(child_name, child_fqn, this, null, cache);
  +         NodeImpl newChild = (NodeImpl) NodeFactory.getInstance().createNode(child_name, child_fqn, this, null, cache);
            if (newChild == null)
            {
               throw new IllegalStateException();
  @@ -632,8 +628,25 @@
   
      public void removeChild(Fqn fqn)
      {
  +      if (cache.getInvocationContext().getOptionOverrides().isBypassInterceptorChain())
  +      {
  +         if (fqn.size() == 1)
  +         {
  +            children.remove(fqn.getName());
  +         }
  +         else
  +         {
  +            Node c = getChild(fqn);
  +            cache.getInvocationContext().getOptionOverrides().setBypassInterceptorChain(true);
  +            c.getParent().removeChild(new Fqn(fqn.getName()));
  +         }
  +         cache.getInvocationContext().getOptionOverrides().setBypassInterceptorChain(false);
  +      }
  +      else
  +      {
         cache.removeChild(new Fqn(getFqn(), fqn));
      }
  +   }
   
      public Map<Object, Node> getChildrenMap()
      {
  @@ -752,7 +765,7 @@
         }
   
         // process children
  -      for (Map.Entry<Object, Node> me : children.entrySet())
  +      for (Map.Entry<Object, AbstractNode> me : children.entrySet())
         {
            NodeSPI n = me.getValue().getNodeSPI();
            Fqn cfqn = new Fqn(fqn, me.getKey());
  @@ -780,7 +793,7 @@
   
      public Set<Node> getChildren()
      {
  -      return new ChildrenNodes();
  +      return new ChildrenNodes<Node>(false);
      }
   
      public synchronized Map<Object, Object> getRawData()
  @@ -839,7 +852,9 @@
      {
         // TODO remove this
         if (!dataLoaded && !data().isEmpty())
  +      {
            log.warn("data exists, but setDataLoaded(false)", new Throwable());
  +      }
   
         this.dataLoaded = dataLoaded;
      }
  @@ -907,8 +922,20 @@
   
      }
   
  -   private class ChildrenNodes extends AbstractSet
  +   private class ChildrenNodes<T> extends AbstractSet
  +   {
  +      private boolean includeDeleted;
  +
  +      public ChildrenNodes(boolean includeDeleted)
      {
  +         this.includeDeleted = includeDeleted;
  +      }
  +
  +      @Override
  +      public boolean contains(Object o)
  +      {
  +         return children != null && children.containsValue(o);
  +      }
   
         @Override
         public Iterator iterator()
  
  
  



More information about the jboss-cvs-commits mailing list