[jboss-cvs] JBossCache/tests/functional/org/jboss/cache/loader ...

Galder Zamarreno galder.zamarreno at jboss.com
Fri Jun 29 09:33:37 EDT 2007


  User: gzamarreno
  Date: 07/06/29 09:33:37

  Modified:    tests/functional/org/jboss/cache/loader       Tag:
                        Branch_JBossCache_1_4_0 CacheLoaderTestsBase.java
                        ClusteredCacheLoaderTest.java
                        AbstractCacheLoaderTestBase.java
                        LocalDelegatingCacheLoaderTest.java
  Added:       tests/functional/org/jboss/cache/loader       Tag:
                        Branch_JBossCache_1_4_0
                        DummyInMemoryCacheLoaderTest.java
                        DummyInMemoryCacheLoader.java
  Log:
  [JBCACHE-1103] Finished the backport from head.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.24.2.2  +176 -1    JBossCache/tests/functional/org/jboss/cache/loader/CacheLoaderTestsBase.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: CacheLoaderTestsBase.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/tests/functional/org/jboss/cache/loader/CacheLoaderTestsBase.java,v
  retrieving revision 1.24.2.1
  retrieving revision 1.24.2.2
  diff -u -b -r1.24.2.1 -r1.24.2.2
  --- CacheLoaderTestsBase.java	5 Dec 2006 15:27:51 -0000	1.24.2.1
  +++ CacheLoaderTestsBase.java	29 Jun 2007 13:33:36 -0000	1.24.2.2
  @@ -12,10 +12,15 @@
   import java.io.Serializable;
   import java.util.*;
   
  +import EDU.oswego.cs.dl.util.concurrent.CountDown;
  +import EDU.oswego.cs.dl.util.concurrent.CopyOnWriteArraySet;
  +
   /**
    * Commons tests for all CacheLoaders
    * @author Bela Ban
  - * @version $Id: CacheLoaderTestsBase.java,v 1.24.2.1 2006/12/05 15:27:51 msurtani Exp $
  + * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
  + * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
  + * @version $Id: CacheLoaderTestsBase.java,v 1.24.2.2 2007/06/29 13:33:36 gzamarreno Exp $
    */
   abstract public class CacheLoaderTestsBase extends AbstractCacheLoaderTestBase {
   
  @@ -1656,7 +1661,177 @@
          assertEquals(value, loader.get(fqn).get(key));
      }
   
  +   public void testCacheLoaderThreadSafety() throws Exception
  +   {
  +      threadSafetyTest(true);
  +   }
  +
  +   public void testCacheLoaderThreadSafetyMultipleFqns() throws Exception
  +   {
  +      threadSafetyTest(false);
  +   }
  +
  +   protected void threadSafetyTest(final boolean singleFqn) throws Exception
  +   {
  +      final CountDown latch = new CountDown(1);
  +      final Fqn fqn = Fqn.fromString("/a/b/c");
  +      final List fqns = new ArrayList(30);
  +      final Random r = new Random();
  +      if (!singleFqn)
  +      {
  +         for (int i = 0; i < 30; i++)
  +         {
  +            Fqn f = Fqn.fromString("/a/b/c/" + i);
  +            fqns.add(f);
  +            loader.put(f, "k", "v");
  +         }
  +      }
  +      else
  +      {
  +         loader.put(fqn, "k", "v");
  +      }
  +      final int loops = 1000;
  +      final Set exceptions = new CopyOnWriteArraySet();
  +
  +      Thread remover1 = new Thread("Remover-1")
  +      {
  +         public void run()
  +         {
  +            try
  +            {
  +               latch.acquire();
  +               for (int i = 0; i < loops; i++)
  +               {
  +                  loader.remove(singleFqn ? fqn : (Fqn)fqns.get(r.nextInt(fqns.size())));
  +               }
  +            }
  +            catch (Exception e)
  +            {
  +               exceptions.add(e);
  +            }
  +         }
  +      };
  +
  +      remover1.start();
  +
  +      Thread remover2 = new Thread("Remover-2")
  +      {
  +         public void run()
  +         {
  +            try
  +            {
  +               latch.acquire();
  +               for (int i = 0; i < loops; i++)
  +               {
  +                  loader.remove(singleFqn ? fqn : (Fqn)fqns.get(r.nextInt(fqns.size())), "k");
  +               }
  +            }
  +            catch (Exception e)
  +            {
  +               exceptions.add(e);
  +            }
  +         }
  +      };
  +
  +      remover2.start();
   
   
  +      Thread reader1 = new Thread("Reader-1")
  +      {
  +         public void run()
  +         {
  +            try
  +            {
  +               latch.acquire();
  +               for (int i = 0; i < loops; i++)
  +               {
  +                  loader.get(singleFqn ? fqn : (Fqn)fqns.get(r.nextInt(fqns.size())));
  +               }
  +            }
  +            catch (Exception e)
  +            {
  +               exceptions.add(e);
  +            }
  +         }
  +      };
  +      reader1.start();
  +
  +      Thread reader2 = new Thread("Reader-2")
  +      {
  +         public void run()
  +         {
  +            try
  +            {
  +               latch.acquire();
  +               for (int i = 0; i < loops; i++)
  +               {
  +                  loader.getChildrenNames(singleFqn ? fqn : (Fqn)fqns.get(r.nextInt(fqns.size())));
  +               }
  +            }
  +            catch (Exception e)
  +            {
  +               exceptions.add(e);
  +            }
  +         }
  +      };
  +      reader2.start();
  +
  +
  +      Thread writer1 = new Thread("Writer-1")
  +      {
  +         public void run()
  +         {
  +            try
  +            {
  +               latch.acquire();
  +               for (int i = 0; i < loops; i++)
  +               {
  +                  loader.put(singleFqn ? fqn : (Fqn)fqns.get(r.nextInt(fqns.size())), "k", "v");
  +               }
  +            }
  +            catch (Exception e)
  +            {
  +               exceptions.add(e);
  +            }
  +         }
  +      };
  +      writer1.start();
  +
  +      Thread writer2 = new Thread("Writer-2")
  +      {
  +         public void run()
  +         {
  +            try
  +            {
  +               latch.acquire();
  +               for (int i = 0; i < loops; i++)
  +               {
  +                  loader.put(singleFqn ? fqn : (Fqn)fqns.get(r.nextInt(fqns.size())), new HashMap());
  +               }
  +            }
  +            catch (Exception e)
  +            {
  +               exceptions.add(e);
  +            }
  +         }
  +      };
  +      writer2.start();
  +
  +
  +      latch.release();
  +      reader1.join();
  +      reader2.join();
  +      remover1.join();
  +      remover2.join();
  +      writer1.join();
  +      writer2.join();
  +
  +      Exception e;
  +      for(Iterator it = exceptions.iterator(); it.hasNext();)
  +      {
  +         e = (Exception)it.next();
  +         throw e;
  +      }
  +   }
   
   }
  
  
  
  1.7.4.2   +165 -2    JBossCache/tests/functional/org/jboss/cache/loader/ClusteredCacheLoaderTest.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: ClusteredCacheLoaderTest.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/tests/functional/org/jboss/cache/loader/ClusteredCacheLoaderTest.java,v
  retrieving revision 1.7.4.1
  retrieving revision 1.7.4.2
  diff -u -b -r1.7.4.1 -r1.7.4.2
  --- ClusteredCacheLoaderTest.java	5 Mar 2007 13:32:56 -0000	1.7.4.1
  +++ ClusteredCacheLoaderTest.java	29 Jun 2007 13:33:37 -0000	1.7.4.2
  @@ -9,16 +9,20 @@
   import junit.framework.Assert;
   import org.jboss.cache.Fqn;
   import org.jboss.cache.TreeCache;
  +import org.jboss.cache.lock.TimeoutException;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   
  -import java.util.Map;
  -import java.util.Set;
  +import java.util.*;
  +
  +import EDU.oswego.cs.dl.util.concurrent.CountDown;
  +import EDU.oswego.cs.dl.util.concurrent.CopyOnWriteArraySet;
   
   /**
    * Tests ClusteredCacheLoader
    *
    * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
  + * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
    */
   public class ClusteredCacheLoaderTest extends AbstractCacheLoaderTestBase
   {
  @@ -190,4 +194,163 @@
           // and now loader2 should see it
           Assert.assertTrue("should exist", loader2.exists(fqn));
       }
  +
  +    public void testCacheLoaderThreadSafety() throws Exception
  +    {
  +       threadSafetyTest(true);
  +    }
  +
  +    public void testCacheLoaderThreadSafetyMultipleFqns() throws Exception
  +    {
  +       threadSafetyTest(false);
  +    }
  +
  +    protected void threadSafetyTest(final boolean singleFqn) throws Exception
  +    {
  +       final CountDown latch = new CountDown(1);
  +       final Fqn fqn = Fqn.fromString("/a/b/c");
  +       final List fqns = new ArrayList(30);
  +       final Random r = new Random();
  +       if (!singleFqn)
  +       {
  +          for (int i = 0; i < 30; i++)
  +          {
  +             Fqn f = Fqn.fromString("/a/b/c/" + i);
  +             fqns.add(f);
  +             cache2.put(f, "k", "v");
  +             cache1.evict(f);
  +          }
  +       }
  +       else
  +       {
  +          cache2.put(fqn, "k", "v");
  +          cache1.evict(fqn);
  +       }
  +       final int loops = 10000;
  +       final Set exceptions = new CopyOnWriteArraySet();
  +
  +       Thread evictor = new Thread("Evictor")
  +       {
  +          public void run()
  +          {
  +             try
  +             {
  +                latch.acquire();
  +                for (int i = 0; i < loops; i++)
  +                {
  +                   Fqn f = singleFqn ? fqn : (Fqn)fqns.get(r.nextInt(fqns.size()));
  +                   cache1.evict(f);
  +                }
  +             }
  +             catch (TimeoutException te)
  +             {
  +                // doesn't matter if we hit these on occasion
  +             }
  +             catch (Exception e)
  +             {
  +                exceptions.add(e);
  +             }
  +          }
  +       };
  +
  +       evictor.start();
  +
  +       Thread writer = new Thread("Writer")
  +       {
  +          public void run()
  +          {
  +             try
  +             {
  +                latch.acquire();
  +                for (int i = 0; i < loops; i++)
  +                {
  +                   Fqn f = singleFqn ? fqn : (Fqn)fqns.get(r.nextInt(fqns.size()));
  +                   cache2.put(f, "k", "v");
  +                }
  +             }
  +             catch (Exception e)
  +             {
  +                exceptions.add(e);
  +             }
  +          }
  +       };
  +
  +       writer.start();
  +
  +
  +       Thread reader1 = new Thread("Reader-1")
  +       {
  +          public void run()
  +          {
  +             try
  +             {
  +                latch.acquire();
  +                for (int i = 0; i < loops; i++)
  +                {
  +                   loader1.get(singleFqn ? fqn : (Fqn)fqns.get(r.nextInt(fqns.size())));
  +                }
  +             }
  +             catch (Exception e)
  +             {
  +                exceptions.add(e);
  +             }
  +          }
  +       };
  +       reader1.start();
  +
  +       Thread reader2 = new Thread("Reader-2")
  +       {
  +          public void run()
  +          {
  +             try
  +             {
  +                latch.acquire();
  +                for (int i = 0; i < loops; i++)
  +                {
  +                   loader1.getChildrenNames(singleFqn ? fqn.getParent() : ((Fqn)fqns.get(r.nextInt(fqns.size()))).getParent());
  +                }
  +             }
  +             catch (Exception e)
  +             {
  +                exceptions.add(e);
  +             }
  +          }
  +       };
  +       reader2.start();
  +
  +       Thread reader3 = new Thread("Reader-3")
  +       {
  +          public void run()
  +          {
  +             try
  +             {
  +                latch.acquire();
  +                for (int i = 0; i < loops; i++)
  +                {
  +                   loader1.getChildrenNames(singleFqn ? fqn : (Fqn)fqns.get(r.nextInt(fqns.size())));
  +                }
  +             }
  +             catch (Exception e)
  +             {
  +                exceptions.add(e);
  +             }
  +          }
  +       };
  +       reader3.start();
  +
  +       latch.release();
  +       reader1.join();
  +       reader2.join();
  +       reader3.join();
  +       evictor.join();
  +       writer.join();
  +
  +       Exception e;
  +       for(Iterator it = exceptions.iterator(); it.hasNext();)
  +       {
  +          e = (Exception)it.next();
  +          throw e;
  +       }
  +    }
  +   
   }
  
  
  
  1.8.2.1   +20 -13    JBossCache/tests/functional/org/jboss/cache/loader/AbstractCacheLoaderTestBase.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: AbstractCacheLoaderTestBase.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/tests/functional/org/jboss/cache/loader/AbstractCacheLoaderTestBase.java,v
  retrieving revision 1.8
  retrieving revision 1.8.2.1
  diff -u -b -r1.8 -r1.8.2.1
  --- AbstractCacheLoaderTestBase.java	30 May 2006 18:40:25 -0000	1.8
  +++ AbstractCacheLoaderTestBase.java	29 Jun 2007 13:33:37 -0000	1.8.2.1
  @@ -9,6 +9,7 @@
   import junit.framework.TestCase;
   import org.w3c.dom.Element;
   import org.jboss.cache.xml.XmlHelper;
  +import org.jboss.cache.config.CacheLoaderConfig;
   
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
  @@ -17,6 +18,7 @@
    * Very basic test case that provides methods to create a cache loader config.
    *
    * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
  + * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
    */
   public abstract class AbstractCacheLoaderTestBase extends TestCase
   {
  @@ -41,8 +43,13 @@
   
       protected Element getSingleCacheLoaderConfig(String preload, String cacheloaderClass, String properties, boolean async, boolean fetchPersistentState, boolean shared, boolean purgeOnStartup) throws Exception
       {
  +        return getSingleCacheLoaderConfig(false, preload, cacheloaderClass, properties, async, fetchPersistentState, shared, purgeOnStartup);
  +    }
  +
  +    protected Element getSingleCacheLoaderConfig(boolean passivation, String preload, String cacheloaderClass, String properties, boolean async, boolean fetchPersistentState, boolean shared, boolean purgeOnStartup) throws Exception
  +    {
           String xml = "<config>\n" +
  -                "<passivation>false</passivation>\n" +
  +              "<passivation>" + passivation + "</passivation>\n" +
                   "<preload>" + preload + "</preload>\n" +
                   "<cacheloader>\n" +
                   "<class>" + cacheloaderClass + "</class>\n" +
  
  
  
  1.9.4.1   +10 -0     JBossCache/tests/functional/org/jboss/cache/loader/LocalDelegatingCacheLoaderTest.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: LocalDelegatingCacheLoaderTest.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/tests/functional/org/jboss/cache/loader/LocalDelegatingCacheLoaderTest.java,v
  retrieving revision 1.9
  retrieving revision 1.9.4.1
  diff -u -b -r1.9 -r1.9.4.1
  --- LocalDelegatingCacheLoaderTest.java	24 Jan 2006 17:27:25 -0000	1.9
  +++ LocalDelegatingCacheLoaderTest.java	29 Jun 2007 13:33:37 -0000	1.9.4.1
  @@ -33,6 +33,16 @@
         delegating_cache.destroyService();
      }
   
  +   public void testCacheLoaderThreadSafety()
  +   {
  +      // do nothing
  +   }
  +
  +   public void testCacheLoaderThreadSafetyMultipleFqns()
  +   {
  +      // do nothing
  +   }
  +
   
      public static Test suite() {
         return new TestSuite(LocalDelegatingCacheLoaderTest.class);
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.2   +16 -0     JBossCache/tests/functional/org/jboss/cache/loader/DummyInMemoryCacheLoaderTest.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: DummyInMemoryCacheLoaderTest.java
  ===================================================================
  RCS file: DummyInMemoryCacheLoaderTest.java
  diff -N DummyInMemoryCacheLoaderTest.java
  --- /dev/null	1 Jan 1970 00:00:00 -0000
  +++ DummyInMemoryCacheLoaderTest.java	29 Jun 2007 13:33:37 -0000	1.1.2.2
  @@ -0,0 +1,16 @@
  +package org.jboss.cache.loader;
  +
  +/**
  + * Odd that we need a test for a test class, but if we intend to use the {@link org.jboss.cache.loader.DummyInMemoryCacheLoader} as a cache
  + * loader stub then we need to make sure it behaves as a valid cache loader.
  + *
  + * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
  + * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a> 
  + */
  +public class DummyInMemoryCacheLoaderTest extends CacheLoaderTestsBase
  +{
  +   protected void configureCache() throws Exception
  +   {
  +      cache.setCacheLoaderConfiguration(getSingleCacheLoaderConfig("", "org.jboss.cache.loader.DummyInMemoryCacheLoader", "", false, true, false));
  +   }
  +}
  
  
  
  1.9.2.2   +379 -0    JBossCache/tests/functional/org/jboss/cache/loader/DummyInMemoryCacheLoader.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: DummyInMemoryCacheLoader.java
  ===================================================================
  RCS file: DummyInMemoryCacheLoader.java
  diff -N DummyInMemoryCacheLoader.java
  --- /dev/null	1 Jan 1970 00:00:00 -0000
  +++ DummyInMemoryCacheLoader.java	29 Jun 2007 13:33:37 -0000	1.9.2.2
  @@ -0,0 +1,379 @@
  +/*
  + * JBoss, Home of Professional Open Source
  + *
  + * Distributable under LGPL license.
  + * See terms of license at gnu.org.
  + */
  +package org.jboss.cache.loader;
  +
  +import org.apache.commons.logging.Log;
  +import org.apache.commons.logging.LogFactory;
  +import org.jboss.cache.Fqn;
  +import org.jboss.cache.Modification;
  +import org.jboss.cache.TreeCache;
  +import org.jboss.cache.CacheException;
  +import org.jboss.cache.buddyreplication.BuddyManager;
  +import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
  +
  +import java.util.*;
  +
  +import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
  +
  +/**
  + * Dummy cache loader that stores data in memory
  + *
  + * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
  + * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
  + */
  +public class DummyInMemoryCacheLoader implements CacheLoader
  +{
  +   protected Map nodes = new ConcurrentHashMap();
  +   protected Log log = LogFactory.getLog(DummyInMemoryCacheLoader.class);
  +   protected Map transactions = new ConcurrentHashMap();
  +   protected TreeCache cache;
  +
  +
  +   public void setConfig(IndividualCacheLoaderConfig config)
  +   {
  +   }
  +
  +   public IndividualCacheLoaderConfig getConfig()
  +   {
  +      return null;
  +   }
  +
  +   public void setConfig(Properties properties)
  +   {
  +   }
  +
  +   public void setCache(TreeCache c)
  +   {
  +      cache = c;
  +   }
  +
  +   public Set getChildrenNames(Fqn fqn) throws Exception
  +   {
  +      if (log.isDebugEnabled()) log.debug("Calling getChildrenNames on Fqn " + fqn + ".  Data map = " + nodes);
  +      if (!nodes.containsKey(fqn))
  +      {
  +         log.debug("node not in loader");
  +         return null;
  +      }
  +
  +      Set children = findChildren(fqn);
  +      log.debug("Fqn " + fqn + " has children " + children);
  +      // to keep in line with the CacheLoader interface contract for this method.
  +      return children.size() == 0 ? null : children;
  +   }
  +
  +   private Set findChildren(Fqn p)
  +   {
  +      Set c = new HashSet();
  +      Fqn f;
  +      for(Iterator it = nodes.keySet().iterator(); it.hasNext();)
  +      {
  +         f = (Fqn)it.next();
  +         if (!f.isRoot() && f.getParent().equals(p))
  +         {
  +            c.add(f.getLast());
  +         }
  +      }
  +      return c;
  +   }
  +
  +   public Map get(Fqn name) throws Exception
  +   {
  +      DummyNode dn = (DummyNode)nodes.get(name);
  +      Map d = dn != null ? dn.data : null;
  +
  +      if (log.isDebugEnabled()) log.debug("Getting data for fqn " + name + " = " + d);
  +      return d;
  +   }
  +
  +   public boolean exists(Fqn name) throws Exception
  +   {
  +      return nodes.containsKey(name);
  +   }
  +
  +   public Object put(Fqn name, Object key, Object value) throws Exception
  +   {
  +      DummyNode n = (DummyNode)nodes.get(name);
  +      if (n == null)
  +      {
  +         n = new DummyNode(name);
  +      }
  +      Object old = n.data.put(key, value);
  +      nodes.put(name, n);
  +      // we need to make sure parents get put in as well.
  +      recursivelyPutParentsIfNeeded(name);
  +      if (log.isDebugEnabled()) log.debug("Did a put on " + name + ", data is " + n.data);
  +      return old;
  +   }
  +
  +   public void put(Fqn name, Map attributes) throws Exception
  +   {
  +      DummyNode n = (DummyNode)nodes.get(name);
  +      if (n == null)
  +      {
  +         n = new DummyNode(name);
  +      }
  +      if (attributes != null) n.data.putAll(attributes);
  +      nodes.put(name, n);
  +      // we need to make sure parents get put in as well.
  +      recursivelyPutParentsIfNeeded(name);
  +      if (log.isDebugEnabled()) log.debug("Did a put on " + name + ", data is " + n.data);
  +   }
  +
  +   public void put(List modifications) throws Exception
  +   {
  +      Modification m;
  +      for(Iterator it = modifications.iterator(); it.hasNext();)
  +      {
  +         m = (Modification)it.next();
  +         switch (m.getType())
  +         {
  +            case Modification.PUT_DATA:
  +               put(m.getFqn(), m.getData());
  +               break;
  +            case Modification.PUT_DATA_ERASE:
  +               removeData(m.getFqn());
  +               put(m.getFqn(), m.getData());
  +               break;
  +            case Modification.PUT_KEY_VALUE:
  +               put(m.getFqn(), m.getKey(), m.getValue());
  +               break;
  +            case Modification.REMOVE_DATA:
  +               removeData(m.getFqn());
  +               break;
  +            case Modification.REMOVE_KEY_VALUE:
  +               remove(m.getFqn(), m.getKey());
  +               break;
  +            case Modification.REMOVE_NODE:
  +               remove(m.getFqn());
  +               break;
  +            default:
  +               throw new CacheException("Unknown modificatiobn " + m.getType());
  +         }
  +      }
  +   }
  +
  +   private void recursivelyPutParentsIfNeeded(Fqn node)
  +   {
  +      Fqn parent = node.getParent();
  +      if (nodes.containsKey(parent)) return; // nothing to do.
  +
  +      // else put the parent in.
  +      nodes.put(parent, new DummyNode(parent));
  +      recursivelyPutParentsIfNeeded(parent);
  +   }
  +
  +   public Object remove(Fqn fqn, Object key) throws Exception
  +   {
  +      log.debug("Removing data from " + fqn);
  +      DummyNode n = (DummyNode)nodes.get(fqn);
  +      if (n == null) n = new DummyNode(fqn);
  +      Object old = n.data.remove(key);
  +      nodes.put(fqn, n);
  +      return old;
  +   }
  +
  +   public void remove(Fqn fqn) throws Exception
  +   {
  +      log.debug("Removing fqn " + fqn);
  +      nodes.remove(fqn);
  +      // remove children.
  +      recursivelyRemoveChildren(fqn);
  +   }
  +
  +   private void recursivelyRemoveChildren(Fqn removedParent)
  +   {
  +      Fqn f;
  +      for(Iterator it = nodes.keySet().iterator(); it.hasNext();)
  +      {
  +         f = (Fqn)it.next();
  +         if (f.getParent().equals(removedParent))
  +         {
  +            // remove the child node too
  +            nodes.remove(f);
  +            // and it's children.  Depth first.
  +            recursivelyRemoveChildren(f);
  +         }
  +      }
  +   }
  +
  +   public void removeData(Fqn fqn) throws Exception
  +   {
  +      log.debug("Removing data from " + fqn);
  +      DummyNode n = (DummyNode)nodes.get(fqn);
  +      if (n == null) n = new DummyNode(fqn);
  +      n.data.clear();
  +      nodes.put(fqn, n);
  +   }
  +
  +   public void prepare(Object tx, List modifications, boolean one_phase) throws Exception
  +   {
  +      if (one_phase)
  +      {
  +         put(modifications);
  +      }
  +      else
  +      {
  +         transactions.put(tx, modifications);
  +      }
  +   }
  +
  +   public void commit(Object tx) throws Exception
  +   {
  +      List modifications = (List)transactions.remove(tx);
  +      if (modifications == null)
  +      {
  +         throw new Exception("transaction " + tx + " not found in transaction table");
  +      }
  +      put(modifications);
  +   }
  +
  +   public void rollback(Object tx)
  +   {
  +      transactions.remove(tx);
  +   }
  +
  +   public byte[] loadEntireState() throws Exception
  +   {
  +      return loadState(Fqn.ROOT);
  +   }
  +
  +   public byte[] loadState(Fqn subtree) throws Exception
  +   {
  +      List list = new LinkedList();
  +      getNodeDataList(subtree, list);
  +      if (log.isTraceEnabled()) log.trace("Loading state of " + list.size() + " nodes into stream");
  +      // cache.getMarshaller().objectToObjectStream(list, out, fqn);
  +      return cache.getMarshaller().objectToByteBuffer(list);
  +   }
  +
  +   protected void getNodeDataList(Fqn fqn, List list) throws Exception
  +   {
  +      Map attrs;
  +      Set children_names;
  +      String child_name;
  +      Fqn tmp_fqn;
  +      NodeData nd;
  +
  +      // first handle the current node
  +      attrs = get(fqn);
  +      if (attrs == null || attrs.size() == 0)
  +      {
  +         nd = new NodeData(fqn);
  +      }
  +      else
  +      {
  +         nd = new NodeData(fqn, attrs);
  +      }
  +      //out.writeObject(nd);
  +      list.add(nd);
  +
  +      // then visit the children
  +      children_names = getChildrenNames(fqn);
  +      if (children_names == null)
  +      {
  +         return;
  +      }
  +
  +      for(Iterator it = children_names.iterator(); it.hasNext();)
  +      {      
  +         child_name = (String) it.next();
  +         tmp_fqn = new Fqn(fqn, child_name);
  +         //loadStateHelper(tmp_fqn, out);
  +         getNodeDataList(tmp_fqn, list);
  +      }      
  +   }
  +
  +   public void storeEntireState(byte[] state) throws Exception
  +   {
  +      storeState(Fqn.ROOT, state);
  +   }
  +
  +   public void storeState(Fqn subtree, byte[] state) throws Exception
  +   {
  +      // remove entire existing state
  +      this.remove(subtree);
  +
  +      boolean moveToBuddy = subtree.isChildOf(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN) && subtree.size() > 1;
  +
  +      // store new state
  +      Fqn fqn = null;
  +      //NodeData nd = null;
  +      Object objectFromStream = cache.getMarshaller().objectFromByteBuffer(state);
  +      List nodeData = (List) objectFromStream;
  +
  +      for(Iterator it = nodeData.iterator(); it.hasNext();)
  +      {
  +         NodeData nd = (NodeData) it.next();
  +
  +         if (moveToBuddy)
  +         {
  +            fqn = BuddyManager.getBackupFqn(subtree, nd.getFqn());
  +         }
  +         else
  +         {
  +            fqn = nd.getFqn();
  +         }
  +
  +         if (nd.getAttributes() != null)
  +         {
  +            removeData(fqn);
  +            this.put(fqn, nd.getAttributes());// creates a node with 0 or more attributes
  +         }
  +         else
  +         {
  +            this.put(fqn, null);// creates a node with null attributes
  +         }
  +      }
  +
  +   }
  +
  +
  +   public void create() throws Exception
  +   {
  +   }
  +
  +   public void start() throws Exception
  +   {
  +   }
  +
  +   public void stop()
  +   {
  +   }
  +
  +   public void destroy()
  +   {
  +   }
  +
  +
  +   public class DummyNode
  +   {
  +      Map data = new HashMap();
  +      Fqn fqn;
  +
  +      public DummyNode(Fqn fqn)
  +      {
  +         this.fqn = fqn;
  +      }
  +
  +      public String toString()
  +      {
  +         return "Node{" +
  +                "data=" + data +
  +                ", fqn=" + fqn +
  +                '}';
  +      }
  +   }
  +
  +
  +   public String toString()
  +   {
  +      return "DummyInMemoryCacheLoader{" +
  +             "nodes=" + nodes +
  +             '}';
  +   }
  +}
  
  
  



More information about the jboss-cvs-commits mailing list