[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