JBoss Cache SVN: r5177 - core/trunk/src/test/java/org/jboss/cache/lock.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-01-21 20:08:04 -0500 (Mon, 21 Jan 2008)
New Revision: 5177
Modified:
core/trunk/src/test/java/org/jboss/cache/lock/IdentityLockTest.java
Log:
JBCACHE-1231 - Implicit marshalled values
Modified: core/trunk/src/test/java/org/jboss/cache/lock/IdentityLockTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/lock/IdentityLockTest.java 2008-01-22 01:06:22 UTC (rev 5176)
+++ core/trunk/src/test/java/org/jboss/cache/lock/IdentityLockTest.java 2008-01-22 01:08:04 UTC (rev 5177)
@@ -9,9 +9,13 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.NodeSPI;
import org.jboss.cache.misc.TestingUtil;
import org.jboss.cache.transaction.GlobalTransaction;
+import static org.testng.AssertJUnit.*;
import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
/**
* Testing of different locking semantics.
16 years, 11 months
JBoss Cache SVN: r5176 - in core/trunk/src: main/java/org/jboss/cache and 11 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-01-21 20:06:22 -0500 (Mon, 21 Jan 2008)
New Revision: 5176
Added:
core/trunk/src/main/java/org/jboss/cache/interceptors/MarshalledValueInterceptor.java
core/trunk/src/main/java/org/jboss/cache/marshall/MarshalledValue.java
core/trunk/src/main/java/org/jboss/cache/marshall/MarshalledValueHelper.java
core/trunk/src/main/java/org/jboss/cache/marshall/MarshalledValueMap.java
core/trunk/src/test/java/org/jboss/cache/interceptors/MarshalledValueInterceptorTest.java
core/trunk/src/test/java/org/jboss/cache/marshall/AsyncReplMarshalledValuesTest.java
core/trunk/src/test/java/org/jboss/cache/marshall/MarshalledValueTest.java
core/trunk/src/test/java/org/jboss/cache/marshall/ReturnValueMarshallingMarshalledValuesTest.java
core/trunk/src/test/java/org/jboss/cache/marshall/SyncReplMarshalledValuesTest.java
Modified:
core/trunk/src/main/docbook/userguide/en/modules/configuration_reference.xml
core/trunk/src/main/java/org/jboss/cache/Cache.java
core/trunk/src/main/java/org/jboss/cache/CacheSPI.java
core/trunk/src/main/java/org/jboss/cache/Node.java
core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java
core/trunk/src/main/java/org/jboss/cache/config/Configuration.java
core/trunk/src/main/java/org/jboss/cache/config/Option.java
core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java
core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java
core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java
core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java
core/trunk/src/main/java/org/jboss/cache/marshall/MethodDeclarations.java
core/trunk/src/main/java/org/jboss/cache/notifications/Notifier.java
core/trunk/src/main/java/org/jboss/cache/optimistic/WorkspaceNodeImpl.java
core/trunk/src/test/java/org/jboss/cache/factories/InterceptorChainFactoryTest.java
core/trunk/src/test/java/org/jboss/cache/lock/IdentityLockTest.java
core/trunk/src/test/java/org/jboss/cache/lock/LockReleaseTest.java
core/trunk/src/test/java/org/jboss/cache/marshall/AsyncReplTest.java
core/trunk/src/test/java/org/jboss/cache/marshall/CustomCollectionTest.java
core/trunk/src/test/java/org/jboss/cache/marshall/RegionBasedMarshallingTestBase.java
core/trunk/src/test/java/org/jboss/cache/marshall/ReturnValueMarshallingTest.java
core/trunk/src/test/java/org/jboss/cache/marshall/SelectedClassnameClassLoader.java
core/trunk/src/test/java/org/jboss/cache/marshall/SyncReplTest.java
Log:
JBCACHE-1231 - Implicit marshalled values
Modified: core/trunk/src/main/docbook/userguide/en/modules/configuration_reference.xml
===================================================================
--- core/trunk/src/main/docbook/userguide/en/modules/configuration_reference.xml 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/docbook/userguide/en/modules/configuration_reference.xml 2008-01-22 01:06:22 UTC (rev 5176)
@@ -645,6 +645,11 @@
support use of different classloaders for different cache regions. This defaults to
<literal>false</literal>
if unspecified.
+ <p/>
+ <b>DEPRECATED.</b>
+ This option will disappear in JBoss Cache 3.x. See
+ <literal>UseLazyDeserialization</literal>
+ instead.
</para>
</entry>
</row>
@@ -669,12 +674,21 @@
</entry>
<entry>
- <para>An optional parameter that controls whether JBoss Cache registers a shutdown hook with the JVM
- runtime. Allowed values are <literal>DEFAULT</literal>, <literal>REGISTER</literal> and
- <literal>DONT_REGISTER</literal>. <literal>REGISTER</literal> and <literal>DONT_REGISTER</literal>
- forces or suppresses the registration of a shutdown hook, respectively, and <literal>DEFAULT</literal>
- registers one if an MBean server (other than the JDK default) cannot be found and it is assumed that the
- cache is running in a managed environment. The default if unspecified is, as expected, <literal>DEFAULT</literal>.
+ <para>An optional parameter that controls whether JBoss Cache registers a shutdown hook with the
+ JVM
+ runtime. Allowed values are<literal>DEFAULT</literal>,
+ <literal>REGISTER</literal>
+ and
+ <literal>DONT_REGISTER</literal>.
+ <literal>REGISTER</literal>
+ and
+ <literal>DONT_REGISTER</literal>
+ forces or suppresses the registration of a shutdown hook, respectively, and
+ <literal>DEFAULT</literal>
+ registers one if an MBean server (other than the JDK default) cannot be found and it is assumed
+ that the
+ cache is running in a managed environment. The default if unspecified is, as expected,<literal>
+ DEFAULT</literal>.
</para>
</entry>
</row>
@@ -686,7 +700,8 @@
<entry>
<para>An optional parameter that can be used to enable or disable the use of lazy deserialization
- for cached objects. Defaults to <literal>true</literal>.
+ for cached objects. Defaults to<literal>true</literal>. If lazy deserialization is disabled,
+ support for implicitly using context class loaders registered with the calling thread goes away.
</para>
</entry>
</row>
Modified: core/trunk/src/main/java/org/jboss/cache/Cache.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/Cache.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/Cache.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -240,12 +240,12 @@
* @param fqn fqn of the node to retrieve
* @return a Node object, or a null if the node does not exist.
*/
- Node getNode(Fqn<?> fqn);
+ Node<K, V> getNode(Fqn<?> fqn);
/**
* Convenience method that takes a string representation of an Fqn. Otherwise identical to {@link #getNode(Fqn)}
*/
- Node getNode(String fqn);
+ Node<K, V> getNode(String fqn);
/**
Modified: core/trunk/src/main/java/org/jboss/cache/CacheSPI.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/CacheSPI.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/CacheSPI.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -52,6 +52,23 @@
NodeSPI<K, V> getRoot();
/**
+ * Overrides {@link Cache#getNode(String)} to return a {@link org.jboss.cache.NodeSPI} instead of a {@link org.jboss.cache.Node}.
+ *
+ * @param s string representation of an Fqn
+ * @return a NodeSPI
+ */
+ NodeSPI<K, V> getNode(String s);
+
+ /**
+ * Overrides {@link Cache#getNode(Fqn)} to return a {@link org.jboss.cache.NodeSPI} instead of a {@link org.jboss.cache.Node}.
+ *
+ * @param f an Fqn
+ * @return a NodeSPI
+ */
+ NodeSPI<K, V> getNode(Fqn<?> f);
+
+
+ /**
* Retrieves a reference to a running {@link javax.transaction.TransactionManager}, if one is configured.
* <p/>
* From 2.1.0, Interceptor authors should obtain this by injection rather than this method. See the
Modified: core/trunk/src/main/java/org/jboss/cache/Node.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/Node.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/Node.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -272,19 +272,19 @@
/**
* Tests if a node reference is still valid. A node reference may become invalid if it has been removed, invalidated
* or moved, either locally or remotely. If a node is invalid, it should be fetched again from the cache or a valid
- * parent node. Operations on invalid nodes will throw a {@link org.jboss.cache.NodeNotValidException}.
+ * parent node. Operations on invalid nodes will throw a {@link org.jboss.cache.NodeNotValidException}.
*
* @return true if the node is valid.
*/
boolean isValid();
- /**
+ /**
* Nodes marked resident would be ignored by the eviction algorithms. E.g. if the algorithm is
* "keep LRU 10 nodes" - the resident nodes won't be counted within those 10 nodes,
* and also won't be evicted when the threshold is reached.
* N.B. calling this method won't have any effect on node's eviction, e.g. we won't consider this node as being
* 'used' in a LRU scenario. If the cache is used in a replicated environment then the resident property is NOT
- * replicated across the cluster. Also the property is not transactionable.
+ * replicated across the cluster. Also the property is not transactionable.
*/
boolean isResident();
@@ -295,12 +295,13 @@
/**
* Tests whether this node is configured to be exclusively locked when inserting or removing children.
- * <p />
+ * <p/>
* The default
* value for this is what is configured in the <tt>LockParentForChildInsertRemove</tt> configuration property,
* programatically reachable by querying {@link org.jboss.cache.config.Configuration#isLockParentForChildInsertRemove()}
- * <p />
+ * <p/>
* This can also be configured on a per-node basis using {@link #setLockForChildInsertRemove(boolean)}
+ *
* @return true if the node is configured to be exclusively locked for child insertions and removal, false otherwise.
* @since 2.1.0
*/
@@ -308,9 +309,21 @@
/**
* Configures the behaviour of how this node is locked when adding/removing children.
+ *
* @param lockForChildInsertRemove if true, exclusive locks will be obtained when children are added/removed. If
- * false, a shared "read lock" will be obtained instead.
+ * false, a shared "read lock" will be obtained instead.
* @since 2.1.0
*/
void setLockForChildInsertRemove(boolean lockForChildInsertRemove);
+
+ /**
+ * Method that releases object references of cached objects held in the cache by serializing them to byte buffers.
+ * Cached objects are lazily deserialized when accessed again, based on the calling thread's context class loader.
+ * <p/>
+ * This can be expensive, based on the effort required to serialize cached objects.
+ * <p/>
+ *
+ * @param recursive if true, child nodes will have their object references released as well.
+ */
+ void releaseObjectReferences(boolean recursive);
}
Modified: core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -10,6 +10,7 @@
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.lock.IdentityLock;
+import org.jboss.cache.marshall.MarshalledValue;
import org.jboss.cache.marshall.MethodCall;
import org.jboss.cache.marshall.MethodCallFactory;
import org.jboss.cache.marshall.MethodDeclarations;
@@ -919,4 +920,36 @@
if (data == null) return new HashMap(0);
return new HashMap(data);
}
+
+ public void releaseObjectReferences(boolean recursive)
+ {
+ if (recursive && children != null)
+ {
+ for (Node child : children.values())
+ {
+ child.releaseObjectReferences(recursive);
+ }
+ }
+
+ if (data != null)
+ {
+ for (Object key : data.keySet())
+ {
+ // get the key first, before attempting to serialize stuff since data.get() may deserialize the key if doing
+ // a hashcode() or equals().
+
+ Object value = data.get(key);
+ if (key instanceof MarshalledValue)
+ {
+ ((MarshalledValue) key).compact(true, true);
+ }
+
+ if (value instanceof MarshalledValue)
+ {
+ ((MarshalledValue) value).compact(true, true);
+ }
+
+ }
+ }
+ }
}
Modified: core/trunk/src/main/java/org/jboss/cache/config/Configuration.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/config/Configuration.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/config/Configuration.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -304,6 +304,15 @@
this.evictionConfig = config;
}
+ /**
+ * This is a deprecated configuration option. While it will be supported for the 2.x series for backward compatibility,
+ * expect to see it disappear in 3.x.
+ * <p/>
+ * With {@link #isUseLazyDeserialization()}, which is enabled by default, custom class loaders are handled implicitly.
+ * See the user guide for details on how this is handled.
+ * <p/>
+ */
+ @Deprecated
public void setUseRegionBasedMarshalling(boolean useRegionBasedMarshalling)
{
testImmutability("useRegionBasedMarshalling");
@@ -578,6 +587,15 @@
return lockParentForChildInsertRemove;
}
+ /**
+ * This is a deprecated configuration option. While it will be supported for the 2.x series for backward compatibility,
+ * expect to see it disappear in 3.x.
+ * <p/>
+ * With {@link #isUseLazyDeserialization()}, which is enabled by default, custom class loaders are handled implicitly.
+ * See the user guide for details on how this is handled.
+ * <p/>
+ */
+ @Deprecated
public boolean isUseRegionBasedMarshalling()
{
return useRegionBasedMarshalling;
Modified: core/trunk/src/main/java/org/jboss/cache/config/Option.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/config/Option.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/config/Option.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -250,17 +250,9 @@
'}';
}
- public Option clone()
+ public Option clone() throws CloneNotSupportedException
{
- try
- {
- return (Option) super.clone();
- }
- catch (CloneNotSupportedException e)
- {
- // should never happen!
- throw new RuntimeException(e);
- }
+ return (Option) super.clone();
}
Modified: core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -95,7 +95,7 @@
// load the tx interceptor
addInterceptor(first, TxInterceptor.class);
-
+ if (configuration.isUseLazyDeserialization()) addInterceptor(first, MarshalledValueInterceptor.class);
addInterceptor(first, NotificationInterceptor.class);
switch (configuration.getCacheMode())
Added: core/trunk/src/main/java/org/jboss/cache/interceptors/MarshalledValueInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/MarshalledValueInterceptor.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/MarshalledValueInterceptor.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -0,0 +1,121 @@
+package org.jboss.cache.interceptors;
+
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.marshall.MarshalledValue;
+import org.jboss.cache.marshall.MarshalledValueHelper;
+import org.jboss.cache.marshall.MethodCall;
+import org.jboss.cache.marshall.MethodDeclarations;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Interceptor that handles the wrapping and unwrapping of cached data using {@link org.jboss.cache.marshall.MarshalledValue}s.
+ * Known "excluded" types are not wrapped/unwrapped, which at this time include {@link String}, Java primitives
+ * and their Object wrappers, as well as arrays of excluded types.
+ * <p/>
+ * The {@link org.jboss.cache.marshall.MarshalledValue} wrapper handles lazy deserialization from byte array representations.
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @see org.jboss.cache.marshall.MarshalledValue
+ * @since 2.1.0
+ */
+public class MarshalledValueInterceptor extends Interceptor
+{
+ @Override
+ public Object invoke(InvocationContext context) throws Throwable
+ {
+ MethodCall call = context.getMethodCall();
+ boolean isAPICall = false;
+ int id = call.getMethodId();
+ Set<MarshalledValue> marshalledValues = null;
+
+ // needs to work for *all* API method calls.
+ if (MethodDeclarations.isAPIMethodCall(id) && id != MethodDeclarations.getNodeMethodLocal_id && id != MethodDeclarations.removeNodeMethodLocal_id)
+ {
+ marshalledValues = new HashSet<MarshalledValue>();
+ isAPICall = true;
+ if (trace) log.trace("Is API method; wrapping any args that need to be wrapped");
+ // check arguments for any user-defined objects that may need to be wrapped.
+ Object[] args = call.getArgs();
+ Object[] replacementArgs = new Object[args.length];
+ int counter = -1;
+
+ for (Object o : args)
+ {
+ counter++;
+ if (MarshalledValueHelper.excludeFromMarshalledValueWrapping(o) || isInternalCollection(counter, id))
+ {
+ replacementArgs[counter] = o;
+ }
+ else if (needToReplaceMap(counter, id))
+ {
+ if (trace) log.trace("Wrapping map contents of argument " + counter);
+ replacementArgs[counter] = wrapMap((Map) o, marshalledValues, context);
+ }
+ else
+ {
+ if (trace) log.trace("Wrapping argument " + counter + " which contains type " + o.getClass());
+ replacementArgs[counter] = createAndAddMarshalledValue(o, marshalledValues, context);
+ }
+ }
+ call.setArgs(replacementArgs);
+ }
+
+ Object retVal = nextInterceptor(context);
+
+ if (isAPICall)
+ {
+ if (trace) log.trace("Compacting MarshalledValues created");
+ for (MarshalledValue mv : marshalledValues) mv.compact(false, false);
+
+ if (retVal instanceof MarshalledValue)
+ {
+ if (trace) log.trace("Return value is a MarshalledValue. Unwrapping.");
+ return ((MarshalledValue) retVal).get();
+ }
+ }
+
+ return retVal;
+ }
+
+ /**
+ * prepare methods include Maps and Lists in args. These should not be mistaken for needing wrapping as MarshalledValues.
+ */
+ protected boolean isInternalCollection(int argSubscript, int methodId)
+ {
+ return (methodId == MethodDeclarations.prepareMethod_id && argSubscript == 1) || (methodId == MethodDeclarations.optimisticPrepareMethod_id && (argSubscript == 1 || argSubscript == 2));
+ }
+
+ /**
+ * put(Map) contents should not be wrapped since the map will need to be iterated over. The contents of the Map, however, should be wrapped.
+ */
+ protected boolean needToReplaceMap(int argSubscript, int methodId)
+ {
+ return ((methodId == MethodDeclarations.putDataEraseMethodLocal_id || methodId == MethodDeclarations.putDataMethodLocal_id) &&
+ argSubscript == 2);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Map wrapMap(Map m, Set<MarshalledValue> marshalledValues, InvocationContext ctx)
+ {
+ Map copy = new HashMap();
+ for (Object key : m.keySet())
+ {
+ Object value = m.get(key);
+ copy.put(MarshalledValueHelper.excludeFromMarshalledValueWrapping(key) ? key : createAndAddMarshalledValue(key, marshalledValues, ctx),
+ MarshalledValueHelper.excludeFromMarshalledValueWrapping(value) ? value : createAndAddMarshalledValue(value, marshalledValues, ctx));
+ }
+ return copy;
+ }
+
+ protected MarshalledValue createAndAddMarshalledValue(Object toWrap, Set<MarshalledValue> marshalledValues, InvocationContext ctx)
+ {
+ MarshalledValue mv = new MarshalledValue(toWrap);
+ marshalledValues.add(mv);
+ if (!ctx.isOriginLocal()) mv.setEqualityPreferenceForInstance(false);
+ return mv;
+ }
+}
Modified: core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -434,13 +434,13 @@
return removeNode(Fqn.fromString(fqn));
}
- public Node getNode(Fqn<?> fqn)
+ public NodeSPI<K, V> getNode(Fqn<?> fqn)
{
MethodCall m = MethodCallFactory.create(MethodDeclarations.getNodeMethodLocal_id, fqn);
- return (Node) invoke(m);
+ return (NodeSPI) invoke(m);
}
- public Node getNode(String fqn)
+ public NodeSPI<K, V> getNode(String fqn)
{
return getNode(Fqn.fromString(fqn));
}
Modified: core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -274,12 +274,30 @@
// TODO: Revisit. Is this really threadsafe? See comment in putIfAbsent() - same solution should be applied here too.
assertValid();
Fqn nf = new Fqn(getFqn(), f);
- Option o1 = spi.getInvocationContext().getOptionOverrides().clone();
+ Option o1 = null;
+ try
+ {
+ o1 = spi.getInvocationContext().getOptionOverrides().clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ // should never happen
+ throw new RuntimeException(e);
+ }
Node<K, V> child = getChild(f);
if (child == null)
{
- Option o2 = o1.clone();
+ Option o2 = null;
+ try
+ {
+ o2 = o1.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ // should never happen
+ throw new RuntimeException(e);
+ }
spi.getInvocationContext().setOptionOverrides(o1);
spi.put(nf, null);
@@ -442,6 +460,11 @@
node.setLockForChildInsertRemove(lockForChildInsertRemove);
}
+ public void releaseObjectReferences(boolean recursive)
+ {
+ node.releaseObjectReferences(recursive);
+ }
+
public boolean hasChildrenDirect()
{
return node.hasChildrenDirect();
Modified: core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -52,6 +52,7 @@
protected static final int MAGICNUMBER_GRAVITATERESULT = 19;
protected static final int MAGICNUMBER_SHORT = 20;
protected static final int MAGICNUMBER_MAPCOPY = 21;
+ protected static final int MAGICNUMBER_MARSHALLEDVALUE = 22;
protected static final int MAGICNUMBER_NULL = 99;
protected static final int MAGICNUMBER_SERIALIZABLE = 100;
protected static final int MAGICNUMBER_REF = 101;
@@ -143,12 +144,13 @@
ClassLoader toUse = defaultClassLoader;
Thread current = Thread.currentThread();
ClassLoader old = current.getContextClassLoader();
+ if (old != null) toUse = old;
try
{
if (useRegionBasedMarshalling) // got to check again in case this meth is called directly
{
- log.trace("Writing region " + region + " to stream");
+ if (trace) log.trace("Writing region " + region + " to stream");
Region r = null;
if (region != null) r = regionManager.getRegion(region, false);
if (r != null && r.getClassLoader() != null) toUse = r.getClassLoader();
@@ -301,6 +303,11 @@
throw new IllegalArgumentException("MethodCall does not have a valid method id. Was this method call created with MethodCallFactory?");
}
}
+ else if (o instanceof MarshalledValue)
+ {
+ out.writeByte(MAGICNUMBER_MARSHALLEDVALUE);
+ ((MarshalledValue) o).writeExternal(out);
+ }
else if (o instanceof Fqn)
{
out.writeByte(MAGICNUMBER_FQN);
@@ -550,6 +557,10 @@
retVal = in.readObject();
refMap.put(reference, retVal);
return retVal;
+ case MAGICNUMBER_MARSHALLEDVALUE:
+ MarshalledValue mv = new MarshalledValue();
+ mv.readExternal(in);
+ return mv;
case MAGICNUMBER_METHODCALL:
retVal = unmarshallMethodCall(in, refMap);
return retVal;
Added: core/trunk/src/main/java/org/jboss/cache/marshall/MarshalledValue.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/MarshalledValue.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/MarshalledValue.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -0,0 +1,200 @@
+package org.jboss.cache.marshall;
+
+import org.jboss.cache.CacheException;
+import org.jboss.util.stream.MarshalledValueInputStream;
+
+import java.io.*;
+import java.util.Arrays;
+
+/**
+ * Wrapper that wraps cached data, providing lazy deserialization using the calling thread's context class loader.
+ * <p/>
+ * The {@link org.jboss.cache.interceptors.MarshalledValueInterceptor} handles transparent
+ * wrapping/unwrapping of cached data.
+ * <p/>
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @see org.jboss.cache.interceptors.MarshalledValueInterceptor
+ * @since 2.1.0
+ */
+public class MarshalledValue implements Externalizable
+{
+ protected Object instance;
+ protected byte[] raw;
+ private int cachedHashCode = 0;
+ // by default equals() will test on the istance rather than the byte array if conversion is required.
+ private transient boolean equalityPreferenceForInstance = true;
+
+ public MarshalledValue(Object instance)
+ {
+ if (instance == null) throw new NullPointerException("Null values cannot be wrapped as MarshalledValues!");
+
+ if (instance instanceof Serializable)
+ this.instance = instance;
+ else
+ throw new CacheException(new NotSerializableException("Marshalled values can only wrap Objects that are serializable! Instance of " + instance.getClass() + " won't Serialize."));
+ }
+
+ public MarshalledValue()
+ {
+ // empty ctor for serialization
+ }
+
+ public void setEqualityPreferenceForInstance(boolean equalityPreferenceForInstance)
+ {
+ this.equalityPreferenceForInstance = equalityPreferenceForInstance;
+ }
+
+ public synchronized void serialize()
+ {
+ if (raw == null)
+ {
+ try
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(instance);
+ oos.close();
+ baos.close();
+ // Do NOT set instance to null over here, since it may be used elsewhere (e.g., in a cache listener).
+ // this will be compacted by the MarshalledValueInterceptor when the call returns.
+// instance = null;
+ raw = baos.toByteArray();
+ }
+ catch (Exception e)
+ {
+ throw new
+ CacheException("Unable to marshall value " + instance);
+ }
+ }
+ }
+
+ public synchronized void deserialize()
+ {
+ if (instance == null)
+ {
+ try
+ {
+ ByteArrayInputStream bais = new ByteArrayInputStream(raw);
+ // use a MarshalledValueInputStream since it needs to be aware of any context class loaders on the current thread.
+ ObjectInputStream ois = new MarshalledValueInputStream(bais);
+ instance = ois.readObject();
+ ois.close();
+ bais.close();
+// raw = null;
+ }
+ catch (Exception e)
+ {
+ throw new CacheException("Unable to unmarshall value", e);
+ }
+ }
+ }
+
+ /**
+ * Compacts the references held by this class to a single reference. If only one representation exists this method
+ * is a no-op unless the 'force' parameter is used, in which case the reference held is forcefully switched to the
+ * 'preferred representation'.
+ * <p/>
+ * Either way, a call to compact() will ensure that only one representation is held.
+ * <p/>
+ *
+ * @param preferSerializedRepresentation if true and both representations exist, the serialized representation is favoured. If false, the deserialized representation is preferred.
+ * @param force ensures the preferred representation is maintained and the other released, even if this means serializing or deserializing.
+ */
+ public void compact(boolean preferSerializedRepresentation, boolean force)
+ {
+ // reset the equalityPreference
+ equalityPreferenceForInstance = true;
+ if (force)
+ {
+ if (preferSerializedRepresentation && raw == null) serialize();
+ else if (!preferSerializedRepresentation && instance == null) deserialize();
+ }
+
+ if (instance != null && raw != null)
+ {
+ // need to lose one representation!
+
+ if (preferSerializedRepresentation)
+ {
+ instance = null;
+ }
+ else
+ {
+ raw = null;
+ }
+ }
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException
+ {
+ if (raw == null) serialize();
+ out.writeInt(raw.length);
+ out.write(raw);
+ out.writeInt(hashCode());
+ }
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+ {
+ int size = in.readInt();
+ raw = new byte[size];
+ cachedHashCode = 0;
+ in.read(raw);
+ cachedHashCode = in.readInt();
+ }
+
+ public Object get() throws IOException, ClassNotFoundException
+ {
+ if (instance == null) deserialize();
+ return instance;
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ MarshalledValue that = (MarshalledValue) o;
+
+ // if both versions are serialized or deserialized, just compare the relevant representations.
+ if (raw != null && that.raw != null) return Arrays.equals(raw, that.raw);
+ if (instance != null && that.instance != null) return instance.equals(that.instance);
+
+ // if conversion of one representation to the other is necessary, then see which we prefer converting.
+ if (equalityPreferenceForInstance)
+ {
+ if (instance == null) deserialize();
+ if (that.instance == null) that.deserialize();
+ return instance.equals(that.instance);
+ }
+ else
+ {
+ if (raw == null) serialize();
+ if (that.raw == null) that.serialize();
+ return Arrays.equals(raw, that.raw);
+ }
+ }
+
+ @Override
+ public int hashCode()
+ {
+ if (cachedHashCode == 0)
+ {
+ // always calculate the hashcode based on the instance since this is where we're getting the equals()
+ if (instance == null) deserialize();
+ cachedHashCode = instance.hashCode();
+ if (cachedHashCode == 0) // degenerate case
+ {
+ cachedHashCode = 0xFEED;
+ }
+ }
+ return cachedHashCode;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "MarshalledValue(cachedHashCode=" + cachedHashCode + "; serialized=" + (raw != null) + ")";
+ }
+}
Added: core/trunk/src/main/java/org/jboss/cache/marshall/MarshalledValueHelper.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/MarshalledValueHelper.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/MarshalledValueHelper.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -0,0 +1,56 @@
+package org.jboss.cache.marshall;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.transaction.GlobalTransaction;
+import org.jgroups.Address;
+
+/**
+ * Common functionality used by the {@link org.jboss.cache.interceptors.MarshalledValueInterceptor} and the {@link MarshalledValueMap}.
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @see MarshalledValue
+ * @see org.jboss.cache.interceptors.MarshalledValueInterceptor
+ * @see org.jboss.cache.marshall.MarshalledValueMap
+ * @since 2.1.0
+ */
+public class MarshalledValueHelper
+{
+ /**
+ * Tests whether the type should be excluded from MarshalledValue wrapping.
+ *
+ * @param type type to test. Should not be null.
+ * @return true if it should be excluded from MarshalledValue wrapping.
+ */
+ public static boolean isTypeExcluded(Class type)
+ {
+ return type.equals(String.class) || type.isPrimitive() ||
+ type.equals(Void.class) || type.equals(Boolean.class) || type.equals(Character.class) ||
+ type.equals(Byte.class) || type.equals(Short.class) || type.equals(Integer.class) ||
+ type.equals(Long.class) || type.equals(Float.class) || type.equals(Double.class) ||
+ (type.isArray() && isTypeExcluded(type.getComponentType()));
+ }
+
+ /**
+ * Tests if the type is a JBoss Cache system type, and hence excluded from MarshalledValue wrapping.
+ *
+ * @param type type to test. Should not be null.
+ * @return true if this is a system type.
+ */
+ public static boolean isSystemType(Class type)
+ {
+ return type.equals(Fqn.class) || type.equals(GlobalTransaction.class) || type.equals(Address.class) ||
+ type.equals(MethodCall.class) || type.equals(MarshalledValue.class);
+ }
+
+ /**
+ * Tests if an object should be excluded from being wrapped as a MarshalledValue. Excluded if the object is null or
+ * if it's type returns true when passed into {@link #isTypeExcluded(Class)} or {@link #isSystemType(Class)}.
+ *
+ * @param object object to test
+ * @return true if it is to be excluded from MarshalledValue wrapping.
+ */
+ public static boolean excludeFromMarshalledValueWrapping(Object object)
+ {
+ return object == null || isSystemType(object.getClass()) || isTypeExcluded(object.getClass());
+ }
+}
Added: core/trunk/src/main/java/org/jboss/cache/marshall/MarshalledValueMap.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/MarshalledValueMap.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/MarshalledValueMap.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -0,0 +1,182 @@
+package org.jboss.cache.marshall;
+
+import net.jcip.annotations.Immutable;
+import org.jboss.cache.CacheException;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A Map that is able to wrap/unwrap MarshalledValues in keys or values. Note that calling keySet(), entrySet() or values()
+ * could be expensive if this map is large!!
+ * <p/>
+ * Also note that this is an immutable Map.
+ * <p/>
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @see MarshalledValue
+ * @since 2.1.0
+ */
+@Immutable
+public class MarshalledValueMap implements Map
+{
+ Map delegate;
+ Map<Object, MarshalledValue> marshalledValues;
+
+ public MarshalledValueMap(Map delegate)
+ {
+ this.delegate = delegate;
+ }
+
+ protected MarshalledValue getMarshalledValue(Object o)
+ {
+ if (marshalledValues == null) marshalledValues = new HashMap<Object, MarshalledValue>();
+ if (marshalledValues.containsKey(o)) return marshalledValues.get(o);
+ MarshalledValue mv = new MarshalledValue(o);
+ marshalledValues.put(o, mv);
+ return mv;
+ }
+
+ public int size()
+ {
+ return delegate.size();
+ }
+
+ public boolean isEmpty()
+ {
+ return delegate.isEmpty();
+ }
+
+ public boolean containsKey(Object key)
+ {
+ if (MarshalledValueHelper.excludeFromMarshalledValueWrapping(key))
+ {
+ return delegate.containsKey(key);
+ }
+ else
+ {
+ return delegate.containsKey(getMarshalledValue(key));
+ }
+ }
+
+ public boolean containsValue(Object value)
+ {
+ if (MarshalledValueHelper.excludeFromMarshalledValueWrapping(value))
+ {
+ return delegate.containsValue(value);
+ }
+ else
+ {
+ return delegate.containsValue(getMarshalledValue(value));
+ }
+ }
+
+ public Object get(Object key)
+ {
+ Object retVal;
+ if (MarshalledValueHelper.excludeFromMarshalledValueWrapping(key))
+ {
+ retVal = delegate.get(key);
+ }
+ else
+ {
+ retVal = delegate.get(getMarshalledValue(key));
+ }
+
+ if (retVal instanceof MarshalledValue) try
+ {
+ retVal = ((MarshalledValue) retVal).get();
+ }
+ catch (Exception e)
+ {
+ throw new CacheException("Unable to unmarshall MarshalledValue", e);
+ }
+
+ return retVal;
+ }
+
+ public Object put(Object key, Object value)
+ {
+ throw new UnsupportedOperationException("This is an immutable map!");
+ }
+
+ public Object remove(Object key)
+ {
+ throw new UnsupportedOperationException("This is an immutable map!");
+ }
+
+ public void putAll(Map t)
+ {
+ throw new UnsupportedOperationException("This is an immutable map!");
+ }
+
+ public void clear()
+ {
+ throw new UnsupportedOperationException("This is an immutable map!");
+ }
+
+ public Set keySet()
+ {
+ try
+ {
+ return unmarshallSet(delegate.keySet());
+ }
+ catch (Exception e)
+ {
+ throw new CacheException("Unable to unmarshall MarshalledValues in collection", e);
+ }
+ }
+
+ public Collection values()
+ {
+ try
+ {
+ return unmarshallList(delegate.values());
+ }
+ catch (Exception e)
+ {
+ throw new CacheException("Unable to unmarshall MarshalledValues in collection", e);
+ }
+ }
+
+ public Set entrySet()
+ {
+ try
+ {
+ return unmarshallSet(delegate.entrySet());
+ }
+ catch (Exception e)
+ {
+ throw new CacheException("Unable to unmarshall MarshalledValues in collection", e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Set unmarshallSet(Set set) throws IOException, ClassNotFoundException
+ {
+ Set newSet = new HashSet();
+ for (Object o : set)
+ {
+ newSet.add(o instanceof MarshalledValue ? ((MarshalledValue) o).get() : o);
+ }
+ return Collections.unmodifiableSet(newSet);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected List unmarshallList(Collection c) throws IOException, ClassNotFoundException
+ {
+ List newList = new LinkedList();
+ for (Object o : c)
+ {
+ newList.add(o instanceof MarshalledValue ? ((MarshalledValue) o).get() : o);
+ }
+ return Collections.unmodifiableList(newList);
+ }
+}
Modified: core/trunk/src/main/java/org/jboss/cache/marshall/MethodDeclarations.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/MethodDeclarations.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/MethodDeclarations.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -555,5 +555,17 @@
throw new CacheException("Attempting to look up a versioned equivalent of a non-crud method");
}
}
+
+ /**
+ * Returns true if the method call is declared in the public Cache API. This includes all put, get, remove, getChildrenNames,
+ * exists calls, but not calls like commit, rollback, prepare, block, unblock, etc.
+ *
+ * @param id method call id to test
+ * @return true if this is an API method call.
+ */
+ public static boolean isAPIMethodCall(int id)
+ {
+ return isCrudMethod(id) || isGetMethod(id);
+ }
}
Modified: core/trunk/src/main/java/org/jboss/cache/notifications/Notifier.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/notifications/Notifier.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/notifications/Notifier.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -15,6 +15,7 @@
import org.jboss.cache.InvocationContext;
import org.jboss.cache.buddyreplication.BuddyGroup;
import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.marshall.MarshalledValueMap;
import org.jboss.cache.notifications.annotation.*;
import org.jboss.cache.notifications.event.*;
import static org.jboss.cache.notifications.event.Event.Type.*;
@@ -634,8 +635,8 @@
private static Map copy(Map data)
{
- if (safe(data)) return data;
- return new MapCopy(data);
+ if (safe(data)) return new MarshalledValueMap(data);
+ return new MarshalledValueMap(new MapCopy(data));
}
private void restoreInvocationContext(InvocationContext backup)
Modified: core/trunk/src/main/java/org/jboss/cache/optimistic/WorkspaceNodeImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/optimistic/WorkspaceNodeImpl.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/main/java/org/jboss/cache/optimistic/WorkspaceNodeImpl.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -389,6 +389,11 @@
throw new UnsupportedOperationException();
}
+ public void releaseObjectReferences(boolean recursive)
+ {
+ throw new UnsupportedOperationException();
+ }
+
public NodeSPI<K, V> getChild(Fqn f)
{
if (f.size() > 1)
Modified: core/trunk/src/test/java/org/jboss/cache/factories/InterceptorChainFactoryTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/factories/InterceptorChainFactoryTest.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/test/java/org/jboss/cache/factories/InterceptorChainFactoryTest.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -29,6 +29,7 @@
{
cache = (CacheSPI) new DefaultCacheFactory().createCache(false);
cache.getConfiguration().setCacheMode("LOCAL");
+ cache.getConfiguration().setUseLazyDeserialization(false);
}
@AfterMethod(alwaysRun = true)
Added: core/trunk/src/test/java/org/jboss/cache/interceptors/MarshalledValueInterceptorTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/interceptors/MarshalledValueInterceptorTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/interceptors/MarshalledValueInterceptorTest.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -0,0 +1,140 @@
+package org.jboss.cache.interceptors;
+
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.marshall.MarshalledValueHelper;
+import org.jboss.cache.misc.TestingUtil;
+import org.jboss.cache.util.CachePrinter;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @since 2.1.0
+ */
+@Test(groups = "functional")
+public class MarshalledValueInterceptorTest
+{
+ CacheSPI c;
+
+ @AfterMethod
+ public void tearDown()
+ {
+ TestingUtil.killCaches(c);
+ }
+
+ public void testDefaultInterceptorStack()
+ {
+ c = (CacheSPI) new DefaultCacheFactory().createCache();
+
+ System.out.println(CachePrinter.printCacheInterceptors(c));
+ assert TestingUtil.findInterceptor(c, MarshalledValueInterceptor.class) != null;
+ }
+
+ public void testEnabledInterceptorStack()
+ {
+ Configuration cfg = new Configuration();
+ cfg.setUseLazyDeserialization(true);
+ c = (CacheSPI) new DefaultCacheFactory().createCache(cfg);
+
+ System.out.println(CachePrinter.printCacheInterceptors(c));
+ assert TestingUtil.findInterceptor(c, MarshalledValueInterceptor.class) != null;
+ }
+
+ public void testDisabledInterceptorStack()
+ {
+ Configuration cfg = new Configuration();
+ cfg.setUseLazyDeserialization(false);
+ c = (CacheSPI) new DefaultCacheFactory().createCache(cfg);
+
+ System.out.println(CachePrinter.printCacheInterceptors(c));
+ assert TestingUtil.findInterceptor(c, MarshalledValueInterceptor.class) == null;
+ }
+
+ public void testExcludedTypes()
+ {
+ // Strings
+ assert MarshalledValueHelper.isTypeExcluded(String.class);
+ assert MarshalledValueHelper.isTypeExcluded(String[].class);
+ assert MarshalledValueHelper.isTypeExcluded(String[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(String[][][].class);
+
+ // primitives
+ assert MarshalledValueHelper.isTypeExcluded(void.class);
+ assert MarshalledValueHelper.isTypeExcluded(boolean.class);
+ assert MarshalledValueHelper.isTypeExcluded(char.class);
+ assert MarshalledValueHelper.isTypeExcluded(byte.class);
+ assert MarshalledValueHelper.isTypeExcluded(short.class);
+ assert MarshalledValueHelper.isTypeExcluded(int.class);
+ assert MarshalledValueHelper.isTypeExcluded(long.class);
+ assert MarshalledValueHelper.isTypeExcluded(float.class);
+ assert MarshalledValueHelper.isTypeExcluded(double.class);
+
+ assert MarshalledValueHelper.isTypeExcluded(boolean[].class);
+ assert MarshalledValueHelper.isTypeExcluded(char[].class);
+ assert MarshalledValueHelper.isTypeExcluded(byte[].class);
+ assert MarshalledValueHelper.isTypeExcluded(short[].class);
+ assert MarshalledValueHelper.isTypeExcluded(int[].class);
+ assert MarshalledValueHelper.isTypeExcluded(long[].class);
+ assert MarshalledValueHelper.isTypeExcluded(float[].class);
+ assert MarshalledValueHelper.isTypeExcluded(double[].class);
+
+ assert MarshalledValueHelper.isTypeExcluded(boolean[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(char[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(byte[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(short[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(int[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(long[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(float[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(double[][].class);
+
+ assert MarshalledValueHelper.isTypeExcluded(Void.class);
+ assert MarshalledValueHelper.isTypeExcluded(Boolean.class);
+ assert MarshalledValueHelper.isTypeExcluded(Character.class);
+ assert MarshalledValueHelper.isTypeExcluded(Byte.class);
+ assert MarshalledValueHelper.isTypeExcluded(Short.class);
+ assert MarshalledValueHelper.isTypeExcluded(Integer.class);
+ assert MarshalledValueHelper.isTypeExcluded(Long.class);
+ assert MarshalledValueHelper.isTypeExcluded(Float.class);
+ assert MarshalledValueHelper.isTypeExcluded(Double.class);
+
+ assert MarshalledValueHelper.isTypeExcluded(Boolean[].class);
+ assert MarshalledValueHelper.isTypeExcluded(Character[].class);
+ assert MarshalledValueHelper.isTypeExcluded(Byte[].class);
+ assert MarshalledValueHelper.isTypeExcluded(Short[].class);
+ assert MarshalledValueHelper.isTypeExcluded(Integer[].class);
+ assert MarshalledValueHelper.isTypeExcluded(Long[].class);
+ assert MarshalledValueHelper.isTypeExcluded(Float[].class);
+ assert MarshalledValueHelper.isTypeExcluded(Double[].class);
+
+ assert MarshalledValueHelper.isTypeExcluded(Boolean[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(Character[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(Byte[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(Short[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(Integer[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(Long[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(Float[][].class);
+ assert MarshalledValueHelper.isTypeExcluded(Double[][].class);
+ }
+
+ public void testNonExcludedTypes()
+ {
+ assert !MarshalledValueHelper.isTypeExcluded(Object.class);
+ assert !MarshalledValueHelper.isTypeExcluded(List.class);
+ assert !MarshalledValueHelper.isTypeExcluded(Collection.class);
+ assert !MarshalledValueHelper.isTypeExcluded(Map.class);
+ assert !MarshalledValueHelper.isTypeExcluded(Date.class);
+ assert !MarshalledValueHelper.isTypeExcluded(Thread.class);
+ assert !MarshalledValueHelper.isTypeExcluded(Collection.class);
+ assert !MarshalledValueHelper.isTypeExcluded(new Object()
+ {
+ String blah;
+ }.getClass());
+ }
+}
Modified: core/trunk/src/test/java/org/jboss/cache/lock/IdentityLockTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/lock/IdentityLockTest.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/test/java/org/jboss/cache/lock/IdentityLockTest.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -7,18 +7,12 @@
package org.jboss.cache.lock;
-import static org.testng.AssertJUnit.assertFalse;
-import static org.testng.AssertJUnit.assertTrue;
-import static org.testng.AssertJUnit.fail;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.NodeSPI;
import org.jboss.cache.misc.TestingUtil;
import org.jboss.cache.transaction.GlobalTransaction;
import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
+
/**
* Testing of different locking semantics.
*
@@ -278,6 +272,7 @@
};
t1.start();
+ TestingUtil.sleepThread(100);
t2.start();
TestingUtil.sleepThread(1000);
Modified: core/trunk/src/test/java/org/jboss/cache/lock/LockReleaseTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/lock/LockReleaseTest.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/test/java/org/jboss/cache/lock/LockReleaseTest.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -157,7 +157,7 @@
cache.put(NODE2, KEY, VAL1);
assertEquals("we ran outside of a TX, locks should have been released: ", 0, cache.getNumberOfLocksHeld());
- Set<String> keys = cache.getNode(NODE2).getChildrenNames();
+ Set<Object> keys = cache.getNode(NODE2).getChildrenNames();
System.out.println("keys of " + NODE2 + " are " + keys);
assertEquals("getChildrenNames() called outside the TX should have released all locks", 0,
cache.getNumberOfLocksHeld());
Added: core/trunk/src/test/java/org/jboss/cache/marshall/AsyncReplMarshalledValuesTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/AsyncReplMarshalledValuesTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/AsyncReplMarshalledValuesTest.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -0,0 +1,13 @@
+package org.jboss.cache.marshall;
+
+/**
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @since 2.1.0
+ */
+public class AsyncReplMarshalledValuesTest extends AsyncReplTest
+{
+ public AsyncReplMarshalledValuesTest()
+ {
+ useMarshalledValues = true;
+ }
+}
Modified: core/trunk/src/test/java/org/jboss/cache/marshall/AsyncReplTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/AsyncReplTest.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/AsyncReplTest.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -47,6 +47,7 @@
Address addr_;
Throwable ex_;
private Fqn<String> aop = Fqn.fromString("/aop");
+ protected boolean useMarshalledValues = false;
@BeforeMethod(alwaysRun = true)
public void setUp() throws Exception
@@ -73,7 +74,9 @@
CacheSPI<Object, Object> cache = (CacheSPI<Object, Object>) new DefaultCacheFactory().createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_ASYNC), false);
cache.getConfiguration().setClusterName(name);
// Use marshaller
- cache.getConfiguration().setUseRegionBasedMarshalling(true);
+ cache.getConfiguration().setUseLazyDeserialization(useMarshalledValues);
+ cache.getConfiguration().setUseRegionBasedMarshalling(!useMarshalledValues);
+
cache.create();
cache.start();
return cache;
Modified: core/trunk/src/test/java/org/jboss/cache/marshall/CustomCollectionTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/CustomCollectionTest.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/CustomCollectionTest.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -6,11 +6,13 @@
import org.jboss.cache.Region;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.lock.IsolationLevel;
+import static org.jboss.cache.marshall.CustomCollectionTest.MarshallingMode.*;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -22,10 +24,10 @@
* @author <a href="mailto:manik@jboss.org">Manik Surtani (manik(a)jboss.org)</a>
*/
@Test(groups = {"functional"})
-public class CustomCollectionTest
+public class CustomCollectionTest extends RegionBasedMarshallingTestBase implements Serializable
{
- private Cache<Object, Object> cache1 = null;
- private Cache<Object, Object> cache2 = null;
+ private transient Cache<Object, Object> cache1 = null;
+ private transient Cache<Object, Object> cache2 = null;
private String myListClass = MyList.class.getName();
private String mySetClass = MySet.class.getName();
private String myMapClass = MyMap.class.getName();
@@ -46,55 +48,96 @@
public void testMap() throws Exception
{
- doMapTest(false);
+ doMapTest(DEFAULT_WITHOUT_MARSHALLED_VALUES);
}
public void testMapWithRegions() throws Exception
{
- doMapTest(true);
+ doMapTest(CUSTOM_CLASSLOADER_WITH_REGIONS);
}
+ public void testMapWithMarshalledValues() throws Exception
+ {
+ doMapTest(CUSTOM_CLASSLOADER_WITH_MARSHALLEDVALUES);
+ }
+
+ public void testMapWithMarshalledValuesDefaultClassloader() throws Exception
+ {
+ doMapTest(DEFAULT_WITH_MARSHALLED_VALUES);
+ }
+
public void testSet() throws Exception
{
- doSetTest(false);
+ doSetTest(DEFAULT_WITHOUT_MARSHALLED_VALUES);
}
public void testSetWithRegions() throws Exception
{
- doSetTest(true);
+ doSetTest(CUSTOM_CLASSLOADER_WITH_REGIONS);
}
+ public void testSetWithMarshalledValues() throws Exception
+ {
+ doSetTest(CUSTOM_CLASSLOADER_WITH_MARSHALLEDVALUES);
+ }
+
+ public void testSetWithMarshalledValuesDefaultClassloader() throws Exception
+ {
+ doSetTest(DEFAULT_WITH_MARSHALLED_VALUES);
+ }
+
public void testList() throws Exception
{
- doListTest(false);
+ doListTest(DEFAULT_WITHOUT_MARSHALLED_VALUES);
}
public void testListWithRegions() throws Exception
{
- doListTest(true);
+ doListTest(CUSTOM_CLASSLOADER_WITH_REGIONS);
}
+ public void testListWithMarshalledValues() throws Exception
+ {
+ doListTest(CUSTOM_CLASSLOADER_WITH_MARSHALLEDVALUES);
+ }
+
+ public void testListWithMarshalledValuesDefaultClassloader() throws Exception
+ {
+ doListTest(DEFAULT_WITH_MARSHALLED_VALUES);
+ }
+
+ enum MarshallingMode
+ {
+ DEFAULT_WITH_MARSHALLED_VALUES, DEFAULT_WITHOUT_MARSHALLED_VALUES, CUSTOM_CLASSLOADER_WITH_REGIONS, CUSTOM_CLASSLOADER_WITH_MARSHALLEDVALUES;
+
+ boolean isUsingCustomClassLoader()
+ {
+ return this == CUSTOM_CLASSLOADER_WITH_MARSHALLEDVALUES || this == CUSTOM_CLASSLOADER_WITH_REGIONS;
+ }
+ }
+
@SuppressWarnings("unchecked")
- private void doMapTest(boolean contextClassLoader) throws Exception
+ private void doMapTest(MarshallingMode marshallingMode) throws Exception
{
- ClassLoader customClassLoader = getClassLoader();
+ ClassLoader customClassLoader = getCollectionsClassLoader();
Class mapClass = customClassLoader.loadClass(myMapClass);
- Map map = (Map) (contextClassLoader ? mapClass.newInstance() : new MyMap());
+ Map map = (Map) (marshallingMode.isUsingCustomClassLoader() ? mapClass.newInstance() : new MyMap());
map.put("k", "v");
- if (contextClassLoader)
- {
- enableRegionBasedClassLoading(customClassLoader);
- }
+ configureCaches(customClassLoader, marshallingMode);
cache1.start();
cache2.start();
+ if (marshallingMode == CUSTOM_CLASSLOADER_WITH_MARSHALLEDVALUES)
+ Thread.currentThread().setContextClassLoader(customClassLoader);
cache1.put(fqn("/a"), "key", map);
Object o = cache2.get(fqn("/a"), "key");
+ if (marshallingMode == CUSTOM_CLASSLOADER_WITH_MARSHALLEDVALUES) resetContextClassLoader();
+
assertTrue(o instanceof Map);
- if (contextClassLoader)
+ if (marshallingMode.isUsingCustomClassLoader())
{
assertNotSame(MyMap.class, o.getClass());
assertSame(mapClass, o.getClass());
@@ -108,27 +151,27 @@
}
@SuppressWarnings("unchecked")
- private void doSetTest(boolean contextClassLoader) throws Exception
+ private void doSetTest(MarshallingMode marshallingMode) throws Exception
{
-
- ClassLoader customClassLoader = getClassLoader();
+ ClassLoader customClassLoader = getCollectionsClassLoader();
Class setClass = customClassLoader.loadClass(mySetClass);
- Set set = (Set) (contextClassLoader ? setClass.newInstance() : new MySet());
+ Set set = (Set) (marshallingMode.isUsingCustomClassLoader() ? setClass.newInstance() : new MySet());
set.add("k");
- if (contextClassLoader)
- {
- enableRegionBasedClassLoading(customClassLoader);
- }
+ configureCaches(customClassLoader, marshallingMode);
cache1.start();
cache2.start();
+ if (marshallingMode == CUSTOM_CLASSLOADER_WITH_MARSHALLEDVALUES)
+ Thread.currentThread().setContextClassLoader(customClassLoader);
cache1.put(fqn("/a"), "key", set);
Object o = cache2.get(fqn("/a"), "key");
+ if (marshallingMode == CUSTOM_CLASSLOADER_WITH_MARSHALLEDVALUES) resetContextClassLoader();
+
assertTrue(o instanceof Set);
- if (contextClassLoader)
+ if (marshallingMode.isUsingCustomClassLoader())
{
assertNotSame(MySet.class, o.getClass());
assertSame(setClass, o.getClass());
@@ -142,28 +185,29 @@
}
@SuppressWarnings("unchecked")
- private void doListTest(boolean contextClassLoader) throws Exception
+ private void doListTest(MarshallingMode marshallingMode) throws Exception
{
- ClassLoader customClassLoader = getClassLoader();
+ ClassLoader customClassLoader = getCollectionsClassLoader();
Class listClass = customClassLoader.loadClass(myListClass);
- List list = (List) (contextClassLoader ? listClass.newInstance() : new MyList());
+ List list = (List) (marshallingMode.isUsingCustomClassLoader() ? listClass.newInstance() : new MyList());
list.add("k");
- if (contextClassLoader)
- {
- enableRegionBasedClassLoading(customClassLoader);
- }
+ configureCaches(customClassLoader, marshallingMode);
cache1.start();
cache2.start();
+ if (marshallingMode == CUSTOM_CLASSLOADER_WITH_MARSHALLEDVALUES)
+ Thread.currentThread().setContextClassLoader(customClassLoader);
cache1.put(fqn("/a"), "key", list);
Object o = cache2.get(fqn("/a"), "key");
+ if (marshallingMode == CUSTOM_CLASSLOADER_WITH_MARSHALLEDVALUES) resetContextClassLoader();
+
assertTrue(o instanceof List);
- if (contextClassLoader)
+ if (marshallingMode.isUsingCustomClassLoader())
{
assertSame(listClass, o.getClass());
assertNotSame(MyList.class, o.getClass());
@@ -178,7 +222,7 @@
public void testHarnessClassLoader() throws Exception
{
- Class myListFromCustomLoader = getClassLoader().loadClass(myListClass);
+ Class myListFromCustomLoader = getCollectionsClassLoader().loadClass(myListClass);
assertNotNull(myListFromCustomLoader);
assertFalse(MyList.class.equals(myListFromCustomLoader));
@@ -195,23 +239,31 @@
}
}
- private void enableRegionBasedClassLoading(ClassLoader customClassLoader)
+ private void configureCaches(ClassLoader customClassLoader, MarshallingMode marshallingMode)
{
- cache1.getConfiguration().setUseRegionBasedMarshalling(true);
- Region region1 = cache1.getRegion(fqn("/a"), true);
- region1.registerContextClassLoader(customClassLoader);
-// cache1.getRegionManager().createRegion("/a", customClassLoader);
-// cache1.getMarshaller().defaultMarshaller.registerClassLoader("/a", customClassLoader);
-// cache1.getMarshaller().defaultMarshaller.useRegionBasedMarshalling = true;
- cache2.getConfiguration().setUseRegionBasedMarshalling(true);
- Region region2 = cache2.getRegion(fqn("/a"), true);
- region2.registerContextClassLoader(customClassLoader);
-// cache2.getRegionManager().createRegion("/a", customClassLoader);
-// cache2.getMarshaller().defaultMarshaller.registerClassLoader("/a", customClassLoader);
-// cache2.getMarshaller().defaultMarshaller.useRegionBasedMarshalling = true;
+ switch (marshallingMode)
+ {
+ case CUSTOM_CLASSLOADER_WITH_REGIONS:
+ cache1.getConfiguration().setUseRegionBasedMarshalling(true);
+ Region region1 = cache1.getRegion(fqn("/a"), true);
+ region1.registerContextClassLoader(customClassLoader);
+ cache2.getConfiguration().setUseRegionBasedMarshalling(true);
+ Region region2 = cache2.getRegion(fqn("/a"), true);
+ region2.registerContextClassLoader(customClassLoader);
+ // and carry on to the same setting as DEFAULT_WITHOUT_MARSHALLED_VALUES
+ case DEFAULT_WITHOUT_MARSHALLED_VALUES:
+ cache1.getConfiguration().setUseLazyDeserialization(false);
+ cache2.getConfiguration().setUseLazyDeserialization(false);
+ break;
+ case DEFAULT_WITH_MARSHALLED_VALUES:
+ case CUSTOM_CLASSLOADER_WITH_MARSHALLEDVALUES:
+ cache1.getConfiguration().setUseLazyDeserialization(true);
+ cache2.getConfiguration().setUseLazyDeserialization(true);
+ break;
+ }
}
- private ClassLoader getClassLoader()
+ private ClassLoader getCollectionsClassLoader()
{
String[] includesClasses = {myListClass, mySetClass, myMapClass};
String[] excludesClasses = {};
Added: core/trunk/src/test/java/org/jboss/cache/marshall/MarshalledValueTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/MarshalledValueTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/MarshalledValueTest.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -0,0 +1,375 @@
+package org.jboss.cache.marshall;
+
+import org.jboss.cache.CacheException;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.config.CacheLoaderConfig;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.factories.ComponentRegistry;
+import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.interceptors.Interceptor;
+import org.jboss.cache.interceptors.MarshalledValueInterceptor;
+import org.jboss.cache.loader.DummyInMemoryCacheLoader;
+import org.jboss.cache.misc.TestingUtil;
+import org.jboss.cache.notifications.annotation.CacheListener;
+import org.jboss.cache.notifications.annotation.NodeModified;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.util.Map;
+
+/**
+ * Tests implicit marshalled values
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @since 2.1.0
+ */
+@Test(groups = "functional")
+public class MarshalledValueTest
+{
+ private CacheSPI<Object, Object> cache1, cache2;
+ private MarshalledValueListenerInterceptor mvli;
+
+
+ @BeforeMethod
+ public void setUp()
+ {
+ cache1 = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(UnitTestCacheConfigurationFactory.createConfiguration(Configuration.CacheMode.REPL_SYNC));
+ cache2 = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(UnitTestCacheConfigurationFactory.createConfiguration(Configuration.CacheMode.REPL_SYNC));
+
+ assert TestingUtil.findInterceptor(cache1, MarshalledValueInterceptor.class) != null : "Marshalled value interceptor not in chain!";
+ assert TestingUtil.findInterceptor(cache2, MarshalledValueInterceptor.class) != null : "Marshalled value interceptor not in chain!";
+
+ mvli = new MarshalledValueListenerInterceptor();
+ cache1.addInterceptor(mvli, MarshalledValueInterceptor.class);
+ }
+
+ @AfterMethod
+ public void tearDown()
+ {
+ TestingUtil.killCaches(cache1, cache2);
+ Pojo.serializationCount = 0;
+ Pojo.deserializationCount = 0;
+ }
+
+ private void assertOnlyOneRepresentationExists(MarshalledValue mv)
+ {
+ assert (mv.instance != null && mv.raw == null) || (mv.instance == null && mv.raw != null) : "Only instance or raw representations should exist in a MarshalledValue; never both";
+ }
+
+ private void assertSerialized(MarshalledValue mv)
+ {
+ assert mv.raw != null : "Should be serialized";
+ }
+
+ private void assertDeserialized(MarshalledValue mv)
+ {
+ assert mv.instance != null : "Should be deserialized";
+ }
+
+ private void assertSerializationCounts(int serializationCount, int deserializationCount)
+ {
+ assert Pojo.serializationCount == serializationCount : "Serialization count: expected " + serializationCount + " but was " + Pojo.serializationCount;
+ assert Pojo.deserializationCount == deserializationCount : "Deserialization count: expected " + deserializationCount + " but was " + Pojo.deserializationCount;
+ }
+
+ public void testNonSerializable()
+ {
+ try
+ {
+ cache1.put("/a", "Hello", new Object());
+ assert false : "Should have failed";
+ }
+ catch (CacheException expected)
+ {
+
+ }
+
+ assert mvli.invocationCount == 0 : "Call should not have gone beyond the MarshalledValueInterceptor";
+
+ try
+ {
+ cache1.put("/a", new Object(), "Hello");
+ assert false : "Should have failed";
+ }
+ catch (CacheException expected)
+ {
+
+ }
+
+ assert mvli.invocationCount == 0 : "Call should not have gone beyond the MarshalledValueInterceptor";
+ }
+
+ public void testNodeReleaseObjectValueReferences()
+ {
+ Pojo value = new Pojo();
+ cache1.put("/a", "key", value);
+ assertSerializationCounts(1, 0);
+ NodeSPI<Object, Object> node = cache1.getNode("/a");
+ Object o = node.getDirect("key");
+ assert o instanceof MarshalledValue;
+ MarshalledValue mv = (MarshalledValue) o;
+ assertDeserialized(mv);
+ assert node.get("key").equals(value);
+ assertDeserialized(mv);
+ assertSerializationCounts(1, 0);
+ node.releaseObjectReferences(false);
+ assertSerializationCounts(2, 0);
+ assertOnlyOneRepresentationExists(mv);
+ assertSerialized(mv);
+
+ // now on cache 2
+ node = cache2.getNode("/a");
+ o = node.getDirect("key");
+ assert o instanceof MarshalledValue;
+ mv = (MarshalledValue) o;
+ assertSerialized(mv); // this proves that unmarshalling on the recipient cache instance is lazy
+
+ assert node.get("key").equals(value);
+ assertDeserialized(mv);
+ assertSerializationCounts(2, 1);
+ node.releaseObjectReferences(false);
+ assertSerializationCounts(2, 1);
+ assertOnlyOneRepresentationExists(mv);
+ assertSerialized(mv);
+ }
+
+ public void testNodeReleaseObjectKeyReferences() throws IOException, ClassNotFoundException
+ {
+ Pojo key = new Pojo();
+ cache1.put("/a", key, "value");
+
+ assertSerializationCounts(1, 0);
+
+ NodeSPI<Object, Object> node = cache1.getNode("/a");
+ Object o = node.getKeysDirect().iterator().next();
+ assert o instanceof MarshalledValue;
+ MarshalledValue mv = (MarshalledValue) o;
+ assertDeserialized(mv);
+
+ assert node.get(key).equals("value");
+ assertDeserialized(mv);
+ assertSerializationCounts(1, 0);
+ node.releaseObjectReferences(false);
+ assertSerializationCounts(2, 0);
+ assertOnlyOneRepresentationExists(mv);
+ assertSerialized(mv);
+
+ // now on cache 2
+ node = cache2.getNode("/a");
+ o = node.getKeysDirect().iterator().next();
+ assert o instanceof MarshalledValue;
+ mv = (MarshalledValue) o;
+ assertSerialized(mv);
+ assert node.get(key).equals("value");
+ assertSerializationCounts(2, 1);
+ assertDeserialized(mv);
+ node.releaseObjectReferences(false);
+
+ assertOnlyOneRepresentationExists(mv);
+ assertSerialized(mv);
+ assertSerializationCounts(2, 1);
+ }
+
+ public void testEqualsAndHashCode() throws Exception
+ {
+ Pojo pojo = new Pojo();
+ MarshalledValue mv = new MarshalledValue(pojo);
+ assertDeserialized(mv);
+ int oldHashCode = mv.hashCode();
+
+ mv.serialize();
+ assertSerialized(mv);
+ assert oldHashCode == mv.hashCode();
+
+ MarshalledValue mv2 = new MarshalledValue(pojo);
+ assertSerialized(mv);
+ assertDeserialized(mv2);
+
+ assert mv2.hashCode() == oldHashCode;
+ assert mv.equals(mv2);
+ }
+
+ public void assertUseOfMagicNumbers() throws Exception
+ {
+ Pojo pojo = new Pojo();
+ MarshalledValue mv = new MarshalledValue(pojo);
+
+ Configuration c = new Configuration();
+ ComponentRegistry cr = new ComponentRegistry(c);
+
+ Marshaller marshaller = new CacheMarshaller210();
+ cr.registerComponent(marshaller, Marshaller.class);
+
+ // Wire the marshaller
+ cr.start();
+
+ // start the test
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bout);
+ marshaller.objectToObjectStream(mv, out);
+ out.close();
+ bout.close();
+
+ // check that the rest just contains a byte stream which a MarshalledValue will be able to deserialize.
+ ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bin);
+
+ assert in.read() == CacheMarshaller200.MAGICNUMBER_MARSHALLEDVALUE;
+ MarshalledValue recreated = new MarshalledValue();
+ recreated.readExternal(in);
+
+ // there should be nothing more
+ assert in.available() == 0;
+ in.close();
+ bin.close();
+
+ assertSerialized(recreated);
+ assert recreated.equals(mv);
+
+ // since both objects being compared are serialized, the equals() above should just compare byte arrays.
+ assertSerialized(recreated);
+ assertOnlyOneRepresentationExists(recreated);
+ }
+
+ public void testCacheLoaders() throws CloneNotSupportedException
+ {
+ tearDown();
+ cache1 = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(UnitTestCacheConfigurationFactory.createConfiguration(Configuration.CacheMode.REPL_SYNC), false);
+ cache2 = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(UnitTestCacheConfigurationFactory.createConfiguration(Configuration.CacheMode.REPL_SYNC), false);
+
+ CacheLoaderConfig clc = new CacheLoaderConfig();
+ CacheLoaderConfig.IndividualCacheLoaderConfig iclc = new CacheLoaderConfig.IndividualCacheLoaderConfig();
+ iclc.setClassName(DummyInMemoryCacheLoader.class.getName());
+ clc.addIndividualCacheLoaderConfig(iclc);
+ cache1.getConfiguration().setCacheLoaderConfig(clc);
+ cache2.getConfiguration().setCacheLoaderConfig(clc.clone());
+
+ cache1.start();
+ cache2.start();
+
+ TestingUtil.blockUntilViewsReceived(60000, cache1, cache2);
+
+ Pojo pojo = new Pojo();
+ cache1.put("/a", "key", pojo);
+
+ assertSerializationCounts(1, 0);
+
+ cache2.get("/a", "key");
+
+ assertSerializationCounts(1, 1);
+ }
+
+ public void testCallbackValues()
+ {
+ Listener l = new Listener();
+ cache1.addCacheListener(l);
+ Pojo pojo = new Pojo();
+ cache1.put("/a", "key", pojo);
+
+ assert l.modData.size() == 1;
+ assert l.modData.get("key") instanceof Pojo;
+ assertSerializationCounts(1, 0);
+ }
+
+ public void testRemoteCallbackValues()
+ {
+ Listener l = new Listener();
+ cache2.addCacheListener(l);
+ Pojo pojo = new Pojo();
+ cache1.put("/a", "key", pojo);
+
+ assert l.modData.size() == 1;
+ pojo = (Pojo) l.modData.get("key");
+ assert pojo != null;
+ assertSerializationCounts(1, 1);
+ }
+
+ @CacheListener
+ public static class Listener
+ {
+ Map modData;
+
+ @NodeModified
+ public void nodeModified(NodeModifiedEvent e)
+ {
+ if (!e.isPre()) modData = e.getData();
+ }
+ }
+
+ class MarshalledValueListenerInterceptor extends Interceptor
+ {
+ int invocationCount = 0;
+
+ public Object invoke(InvocationContext ctx) throws Throwable
+ {
+ invocationCount++;
+ MethodCall mc = ctx.getMethodCall();
+ for (Object arg : mc.getArgs())
+ {
+ if (arg instanceof MarshalledValue) assertOnlyOneRepresentationExists((MarshalledValue) arg);
+ }
+
+ Object retval = nextInterceptor(ctx);
+
+ if (retval instanceof MarshalledValue) assertOnlyOneRepresentationExists((MarshalledValue) retval);
+ return retval;
+ }
+ }
+
+ public static class Pojo implements Externalizable
+ {
+ int i;
+ boolean b;
+ static int serializationCount, deserializationCount;
+
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Pojo pojo = (Pojo) o;
+
+ if (b != pojo.b) return false;
+ if (i != pojo.i) return false;
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int result;
+ result = i;
+ result = 31 * result + (b ? 1 : 0);
+ return result;
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException
+ {
+ out.writeInt(i);
+ out.writeBoolean(b);
+ serializationCount++;
+ }
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+ {
+ i = in.readInt();
+ b = in.readBoolean();
+ deserializationCount++;
+ }
+ }
+}
+
+
Modified: core/trunk/src/test/java/org/jboss/cache/marshall/RegionBasedMarshallingTestBase.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/RegionBasedMarshallingTestBase.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/RegionBasedMarshallingTestBase.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -7,14 +7,27 @@
{
protected static final String ADDRESS_CLASSNAME = "org.jboss.cache.marshall.data.Address";
protected static final String PERSON_CLASSNAME = "org.jboss.cache.marshall.data.Person";
+ protected ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
protected ClassLoader getClassLoader() throws Exception
{
String[] includesClasses = {PERSON_CLASSNAME, ADDRESS_CLASSNAME};
- String [] excludesClasses = {};
+ String[] excludesClasses = {};
ClassLoader cl = Thread.currentThread().getContextClassLoader();
return new SelectedClassnameClassLoader(includesClasses, excludesClasses, cl);
}
+ protected ClassLoader getFailingClassLoader() throws Exception
+ {
+ String[] includesClasses = {};
+ String[] excludesClasses = {};
+ String[] failingClasses = {PERSON_CLASSNAME, ADDRESS_CLASSNAME};
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ return new SelectedClassnameClassLoader(includesClasses, excludesClasses, failingClasses, cl);
+ }
+ protected void resetContextClassLoader()
+ {
+ Thread.currentThread().setContextClassLoader(originalClassLoader);
+ }
}
Added: core/trunk/src/test/java/org/jboss/cache/marshall/ReturnValueMarshallingMarshalledValuesTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/ReturnValueMarshallingMarshalledValuesTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/ReturnValueMarshallingMarshalledValuesTest.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -0,0 +1,16 @@
+package org.jboss.cache.marshall;
+
+import org.testng.annotations.Test;
+
+/**
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @since 2.1.0
+ */
+@Test(groups = {"functional", "jgroups"})
+public class ReturnValueMarshallingMarshalledValuesTest extends ReturnValueMarshallingTest
+{
+ public ReturnValueMarshallingMarshalledValuesTest()
+ {
+ useMarshalledValues = true;
+ }
+}
Modified: core/trunk/src/test/java/org/jboss/cache/marshall/ReturnValueMarshallingTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/ReturnValueMarshallingTest.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/ReturnValueMarshallingTest.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -21,8 +21,9 @@
* @since 2.0.0
*/
@Test(groups = {"functional", "jgroups"})
-public class ReturnValueMarshallingTest
+public class ReturnValueMarshallingTest extends RegionBasedMarshallingTestBase
{
+ protected boolean useMarshalledValues = false;
private CacheSPI<Object, Object> cache1, cache2;
private Fqn fqn = Fqn.fromString("/a");
private ClassLoader classLoader;
@@ -34,26 +35,30 @@
public void setUp() throws Exception
{
cache1 = (CacheSPI<Object, Object>) new DefaultCacheFactory().createCache(false);
- cache1.getConfiguration().setUseRegionBasedMarshalling(true);
+ cache1.getConfiguration().setUseLazyDeserialization(useMarshalledValues);
+ cache1.getConfiguration().setUseRegionBasedMarshalling(!useMarshalledValues);
cache1.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
cache1.getConfiguration().setSyncReplTimeout(60000);// to aid with debugging
cache1.start();
cache2 = (CacheSPI<Object, Object>) new DefaultCacheFactory().createCache(false);
- cache2.getConfiguration().setUseRegionBasedMarshalling(true);
+ cache2.getConfiguration().setUseLazyDeserialization(useMarshalledValues);
+ cache2.getConfiguration().setUseRegionBasedMarshalling(!useMarshalledValues);
cache2.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
cache2.getConfiguration().setSyncReplTimeout(60000);// to aid with debugging
cache2.start();
classLoader = getClassLoader();
- Region r1 = cache1.getRegion(fqn, true);
- r1.setActive(true);
- r1.registerContextClassLoader(classLoader);
+ if (!useMarshalledValues)
+ {
+ Region r1 = cache1.getRegion(fqn, true);
+ r1.setActive(true);
+ r1.registerContextClassLoader(classLoader);
+ Region r2 = cache2.getRegion(fqn, true);
+ r2.setActive(true);
+ r2.registerContextClassLoader(classLoader);
+ }
- Region r2 = cache2.getRegion(fqn, true);
- r2.setActive(true);
- r2.registerContextClassLoader(classLoader);
-
listClass = classLoader.loadClass(className);
value = listClass.newInstance();
@@ -64,9 +69,11 @@
public void tearDown()
{
TestingUtil.killCaches(cache1, cache2);
+ resetContextClassLoader();
}
- private ClassLoader getClassLoader()
+ @Override
+ protected ClassLoader getClassLoader()
{
String[] includesClasses = {className};
String[] excludesClasses = {};
@@ -76,6 +83,7 @@
public void testClusteredGet() throws Exception
{
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(classLoader);
assertNotNull(cache1.get(fqn, key));
assertNotSame(MyList.class, cache1.get(fqn, key).getClass());
assertSame(listClass, cache1.get(fqn, key).getClass());
@@ -99,12 +107,14 @@
// now test that the data returned has been marshalled using the appropriate class loader.
assertNotNull(data);
+ if (useMarshalledValues) data = ((MarshalledValue) data).get();
assertNotSame(MyList.class, data.getClass());
assertSame(listClass, data.getClass());
}
public void testDataGravitation() throws Exception
{
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(classLoader);
assertNotNull(cache1.get(fqn, key));
assertNotSame(MyList.class, cache1.get(fqn, key).getClass());
assertSame(listClass, cache1.get(fqn, key).getClass());
@@ -125,6 +135,7 @@
Object value = data.getNodeData().get(0).getAttributes().get(key);
assertNotNull(value);
+ if (useMarshalledValues) value = ((MarshalledValue) value).get();
assertNotSame(MyList.class, value.getClass());
assertSame(listClass, value.getClass());
}
Modified: core/trunk/src/test/java/org/jboss/cache/marshall/SelectedClassnameClassLoader.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/SelectedClassnameClassLoader.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/SelectedClassnameClassLoader.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -131,7 +131,6 @@
protected Class<?> findClass(String name) throws ClassNotFoundException
{
-
log.info("In SelectedClassnameClassLoader.findClass()");
Class result = classes.get(name);
if (result != null)
Added: core/trunk/src/test/java/org/jboss/cache/marshall/SyncReplMarshalledValuesTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/SyncReplMarshalledValuesTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/SyncReplMarshalledValuesTest.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -0,0 +1,22 @@
+package org.jboss.cache.marshall;
+
+import org.testng.annotations.Test;
+
+/**
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @since 2.1.0
+ */
+@Test(groups = {"functional", "jgroups"})
+public class SyncReplMarshalledValuesTest extends SyncReplTest
+{
+ public SyncReplMarshalledValuesTest()
+ {
+ useMarshalledValues = true;
+ }
+
+ @Override
+ public void testCustomFqn()
+ {
+ // meaningless when using marshalled values
+ }
+}
Modified: core/trunk/src/test/java/org/jboss/cache/marshall/SyncReplTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/SyncReplTest.java 2008-01-21 23:13:15 UTC (rev 5175)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/SyncReplTest.java 2008-01-22 01:06:22 UTC (rev 5176)
@@ -44,6 +44,7 @@
Address addr_;
Throwable ex_;
private Fqn aop = Fqn.fromString("/aop");
+ protected boolean useMarshalledValues = false;
@BeforeMethod(alwaysRun = true)
public void setUp() throws Exception
@@ -69,7 +70,9 @@
CacheSPI<Object, Object> cache = (CacheSPI<Object, Object>) new DefaultCacheFactory().createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
cache.getConfiguration().setClusterName(name);
// Use marshaller
- cache.getConfiguration().setUseRegionBasedMarshalling(true);
+ cache.getConfiguration().setUseLazyDeserialization(useMarshalledValues);
+ cache.getConfiguration().setUseRegionBasedMarshalling(!useMarshalledValues);
+
cache.create();
cache.start();
return cache;
@@ -90,6 +93,8 @@
log("stopping cache2");
cache2.stop();
}
+
+ resetContextClassLoader();
}
public void testPlainPut() throws Exception
@@ -102,17 +107,26 @@
public void testCCE() throws Exception
{
- ClassLoader cl = getClassLoader();
- Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
- r1.registerContextClassLoader(cl);
+ ClassLoader c1 = getClassLoader();
+ ClassLoader c2 = getClassLoader();
- cl = getClassLoader();
- Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
- r2.registerContextClassLoader(cl);
+ if (!useMarshalledValues)
+ {
+ Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
+ r1.registerContextClassLoader(c1);
+
+ Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
+ r2.registerContextClassLoader(c2);
+ }
+
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(c1);
cache1.put(aop, "person", ben_);
+ if (useMarshalledValues) resetContextClassLoader();
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(getFailingClassLoader());
try
{
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(c2);
@SuppressWarnings("unused")
Person person = (Person) cache2.get(aop, "person");
}
@@ -127,16 +141,20 @@
public void testPut() throws Exception
{
ClassLoader cla = getClassLoader();
- Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
- r1.registerContextClassLoader(cla);
ClassLoader clb = getClassLoader();
- Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
- r2.registerContextClassLoader(clb);
-
+ if (!useMarshalledValues)
+ {
+ Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
+ r1.registerContextClassLoader(cla);
+ Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
+ r2.registerContextClassLoader(clb);
+ }
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(cla);
cache1.put(aop, "person", ben_);
Object ben2;
- // Can't cast it to Person. CCE will resutl.
+ // Can't cast it to Person. CCE will result.
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(clb);
ben2 = cache2.get(aop, "person");
assertEquals(ben_.toString(), ben2.toString());
}
@@ -144,35 +162,31 @@
public void testCLSet() throws Exception
{
ClassLoader cla = getClassLoader();
- Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
- r1.registerContextClassLoader(cla);
ClassLoader clb = getClassLoader();
- Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
- r2.registerContextClassLoader(clb);
+ if (!useMarshalledValues)
+ {
+ Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
+ r1.registerContextClassLoader(cla);
+ Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
+ r2.registerContextClassLoader(clb);
+ }
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(cla);
cache1.put(aop, "person", ben_);
Object ben2;
- // Can't cast it to Person. CCE will resutl.
+ // Can't cast it to Person. CCE will result.
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(clb);
ben2 = cache2.get(aop, "person");
assertEquals(ben_.toString(), ben2.toString());
Class claz = clb.loadClass(ADDRESS_CLASSNAME);
Object add = claz.newInstance();
- {
- Class[] types = {String.class};
- Method setValue = claz.getMethod("setCity", types);
- Object[] margs = {"Sunnyvale"};
- setValue.invoke(add, margs);
- }
-
- {
- Class clasz1 = clb.loadClass(PERSON_CLASSNAME);
- Class[] types = {claz};
- Method setValue = clasz1.getMethod("setAddress", types);
- Object[] margs = {add};
- setValue.invoke(ben2, margs);
- }
+ Method setValue = claz.getMethod("setCity", String.class);
+ setValue.invoke(add, "Sunnyvale");
+ Class clasz1 = clb.loadClass(PERSON_CLASSNAME);
+ setValue = clasz1.getMethod("setAddress", claz);
+ setValue.invoke(ben2, add);
}
/**
@@ -183,111 +197,121 @@
public void testCLSet2() throws Exception
{
ClassLoader cla = getClassLoader();
- Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
- r1.registerContextClassLoader(cla);
ClassLoader clb = getClassLoader();
- Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
- r2.registerContextClassLoader(clb);
+ if (!useMarshalledValues)
+ {
+ Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
+ r1.registerContextClassLoader(cla);
+ Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
+ r2.registerContextClassLoader(clb);
+ }
+
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(cla);
cache1.put(aop, "person", ben_);
Object ben2;
- // Can't cast it to Person. CCE will resutl.
+ // Can't cast it to Person. CCE will result.
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(clb);
ben2 = cache2.get(aop, "person");
assertEquals(ben_.toString(), ben2.toString());
Class claz = clb.loadClass(ADDRESS_CLASSNAME);
Object add = claz.newInstance();
- {
- Class[] types = {String.class};
- Method setValue = claz.getMethod("setCity", types);
- Object[] margs = {"Sunnyvale"};
- setValue.invoke(add, margs);
- }
+ Method setValue = claz.getMethod("setCity", String.class);
+ setValue.invoke(add, "Sunnyvale");
+ Class clasz1 = clb.loadClass(PERSON_CLASSNAME);
+ setValue = clasz1.getMethod("setAddress", claz);
+ setValue.invoke(ben2, add);
- {
- Class clasz1 = clb.loadClass(PERSON_CLASSNAME);
- Class[] types = {claz};
- Method setValue = clasz1.getMethod("setAddress", types);
- Object[] margs = {add};
- setValue.invoke(ben2, margs);
- }
-
// Set it back to the cache
// Can't cast it to Person. CCE will resutl.
cache2.put(aop, "person", ben2);
+
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(cla);
Object ben3 = cache1.get(aop, "person");
assertEquals(ben2.toString(), ben3.toString());
-
}
public void testPuts() throws Exception
{
- ClassLoader cl = getClassLoader();
- Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
- r1.registerContextClassLoader(cl);
+ ClassLoader cla = getClassLoader();
+ ClassLoader clb = getClassLoader();
+ if (!useMarshalledValues)
+ {
+ Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
+ r1.registerContextClassLoader(cla);
+ Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
+ r2.registerContextClassLoader(clb);
+ }
+
// Create an empty Person loaded by this classloader
- Object scopedBen1 = getPersonFromClassloader(cl);
-
- cl = getClassLoader();
- Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
- r2.registerContextClassLoader(cl);
-
+ Object scopedBen1 = getPersonFromClassloader(cla);
// Create another empty Person loaded by this classloader
- Object scopedBen2 = getPersonFromClassloader(cl);
+ Object scopedBen2 = getPersonFromClassloader(clb);
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(cla);
cache1.put(Fqn.fromString("/aop/1"), "person", ben_);
cache1.put(Fqn.fromString("/aop/2"), "person", scopedBen1);
+ if (useMarshalledValues) resetContextClassLoader();
+ Object ben2;
+ // Can't cast it to Person. CCE will resutl.
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(clb);
+ ben2 = cache2.get(Fqn.fromString("/aop/1"), "person");
+ if (useMarshalledValues) resetContextClassLoader();
+ assertEquals(ben_.toString(), ben2.toString());
- Object ben2 = null;
- try
- {
- // Can't cast it to Person. CCE will resutl.
- ben2 = cache2.get(Fqn.fromString("/aop/1"), "person");
- assertEquals(ben_.toString(), ben2.toString());
-
- ben2 = cache2.get(Fqn.fromString("/aop/2"), "person");
- assertFalse("cache2 deserialized with scoped classloader", ben2 instanceof Person);
- assertFalse("cache2 deserialized with cache2 classloader", scopedBen1.equals(ben2));
- assertEquals("scopedBen deserialized properly", scopedBen2, ben2);
- }
- catch (Exception ex)
- {
- fail("Test fails with exception " + ex);
- }
-
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(clb);
+ ben2 = cache2.get(Fqn.fromString("/aop/2"), "person");
+ if (useMarshalledValues) resetContextClassLoader();
+ assertFalse("cache2 deserialized with scoped classloader", ben2 instanceof Person);
+ assertFalse("cache2 deserialized with cache2 classloader", scopedBen1.equals(ben2));
+ assertEquals("scopedBen deserialized properly", scopedBen2, ben2);
}
public void testMethodCall() throws Exception
{
- ClassLoader cl = getClassLoader();
- Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
- r1.registerContextClassLoader(cl);
- cl = getClassLoader();
- Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
- r2.registerContextClassLoader(cl);
+ ClassLoader cla = getClassLoader();
+ ClassLoader clb = getClassLoader();
+ if (!useMarshalledValues)
+ {
+ Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
+ r1.registerContextClassLoader(cla);
+
+ Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
+ r2.registerContextClassLoader(clb);
+ }
+
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(cla);
cache1.put(Fqn.fromString("/aop/1"), "person", ben_);
cache1.remove(Fqn.fromString("/aop/1"), "person");
HashMap<Object, Object> map = new HashMap<Object, Object>();
map.put("1", "1");
map.put("2", "2");
+
cache1.put(Fqn.fromString("/aop/2"), map);
cache1.removeNode(Fqn.fromString("/aop/2"));
-
+ if (useMarshalledValues) resetContextClassLoader();
TestingUtil.sleepThread(1000);
}
public void testTxMethodCall() throws Exception
{
- ClassLoader cl = getClassLoader();
- Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
- r1.registerContextClassLoader(cl);
- cl = getClassLoader();
- Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
- r2.registerContextClassLoader(cl);
+ ClassLoader cla = getClassLoader();
+ ClassLoader clb = getClassLoader();
+ if (!useMarshalledValues)
+ {
+ Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
+ r1.registerContextClassLoader(cla);
+
+ Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
+ r2.registerContextClassLoader(clb);
+ }
+
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(cla);
TransactionManager tm = beginTransaction();
cache1.put(Fqn.fromString("/aop/1"), "person", ben_);
cache1.remove(Fqn.fromString("/aop/1"), "person");
@@ -299,70 +323,53 @@
tm.commit();
TestingUtil.sleepThread(1000);
+ if (useMarshalledValues) resetContextClassLoader();
}
- public void testTxPut() throws Exception
- {
- TransactionManager tm = beginTransaction();
- cache1.put(aop, "person", ben_);
- cache1.put(aop, "person1", ben_);
- cache1.removeNode(aop);
- cache1.put(aop, "person", ben_);
- tm.commit();
- Person ben2 = (Person) cache2.get(aop, "person");
- assertNotNull("Person from 2nd cache should not be null ", ben2);
- assertEquals(ben_.toString(), ben2.toString());
- }
-
- public void testTxRollback() throws Exception
- {
- TransactionManager tm = beginTransaction();
- cache1.put(aop, "person", ben_);
- cache1.put(aop, "person1", ben_);
- tm.rollback();
- Person ben2 = (Person) cache2.get(aop, "person");
- assertNull("Person from 2nd cache should be null ", ben2);
- }
-
public void testTxCLSet2() throws Exception
{
ClassLoader cla = getClassLoader();
- Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
- r1.registerContextClassLoader(cla);
+ if (!useMarshalledValues)
+ {
+ Region r1 = cache1.getRegion(aop, false) == null ? cache1.getRegion(aop, true) : cache1.getRegion(aop, false);
+ r1.registerContextClassLoader(cla);
+ }
ClassLoader clb = getClassLoader();
- Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
- r2.registerContextClassLoader(clb);
+ if (!useMarshalledValues)
+ {
+ Region r2 = cache2.getRegion(aop, false) == null ? cache2.getRegion(aop, true) : cache2.getRegion(aop, false);
+ r2.registerContextClassLoader(clb);
+ }
TransactionManager tm = beginTransaction();
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(cla);
cache1.put(aop, "person", ben_);
tm.commit();
+ if (useMarshalledValues) resetContextClassLoader();
Object ben2;
// Can't cast it to Person. CCE will resutl.
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(clb);
ben2 = cache2.get(aop, "person");
+ if (useMarshalledValues) resetContextClassLoader();
assertEquals(ben_.toString(), ben2.toString());
Class claz = clb.loadClass(ADDRESS_CLASSNAME);
Object add = claz.newInstance();
- {
- Class[] types = {String.class};
- Method setValue = claz.getMethod("setCity", types);
- Object[] margs = {"Sunnyvale"};
- setValue.invoke(add, margs);
- }
+ Method setValue = claz.getMethod("setCity", String.class);
+ setValue.invoke(add, "Sunnyvale");
+ Class clasz1 = clb.loadClass(PERSON_CLASSNAME);
+ setValue = clasz1.getMethod("setAddress", claz);
+ setValue.invoke(ben2, add);
- {
- Class clasz1 = clb.loadClass(PERSON_CLASSNAME);
- Class[] types = {claz};
- Method setValue = clasz1.getMethod("setAddress", types);
- Object[] margs = {add};
- setValue.invoke(ben2, margs);
- }
-
// Set it back to the cache
// Can't cast it to Person. CCE will resutl.
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(clb);
cache2.put(aop, "person", ben2);
+ if (useMarshalledValues) resetContextClassLoader();
+ if (useMarshalledValues) Thread.currentThread().setContextClassLoader(cla);
Object ben3 = cache1.get(aop, "person");
+ if (useMarshalledValues) resetContextClassLoader();
assertEquals(ben2.toString(), ben3.toString());
}
16 years, 11 months
JBoss Cache SVN: r5175 - benchmarks/CacheTests/trunk/lib.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2008-01-21 18:13:15 -0500 (Mon, 21 Jan 2008)
New Revision: 5175
Modified:
benchmarks/CacheTests/trunk/lib/jboss-aop.jar
benchmarks/CacheTests/trunk/lib/jbosscache-core.jar
benchmarks/CacheTests/trunk/lib/jbosscache-pojo.jar
Log:
Update to the following versions:
POJO Cache 2.1.SNAPSHOT
Core Cache 2.1.0.CR3
AOP 2.1.0.CR3
Modified: benchmarks/CacheTests/trunk/lib/jboss-aop.jar
===================================================================
(Binary files differ)
Modified: benchmarks/CacheTests/trunk/lib/jbosscache-core.jar
===================================================================
(Binary files differ)
Modified: benchmarks/CacheTests/trunk/lib/jbosscache-pojo.jar
===================================================================
(Binary files differ)
16 years, 11 months
JBoss Cache SVN: r5174 - pojo/branches/2.1.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2008-01-21 17:52:16 -0500 (Mon, 21 Jan 2008)
New Revision: 5174
Modified:
pojo/branches/2.1/pom.xml
Log:
Depend on core CR3
Modified: pojo/branches/2.1/pom.xml
===================================================================
--- pojo/branches/2.1/pom.xml 2008-01-21 22:51:17 UTC (rev 5173)
+++ pojo/branches/2.1/pom.xml 2008-01-21 22:52:16 UTC (rev 5174)
@@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<properties>
<jbosscache-pojo-version>2.1.0.CR4</jbosscache-pojo-version>
- <jbosscache-core-version>2.1.0.CR4</jbosscache-core-version>
+ <jbosscache-core-version>2.1.0.CR3</jbosscache-core-version>
<jboss.aop.version>2.0.0.CR3</jboss.aop.version>
</properties>
<parent>
16 years, 11 months
JBoss Cache SVN: r5173 - pojo/branches/2.1.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2008-01-21 17:51:17 -0500 (Mon, 21 Jan 2008)
New Revision: 5173
Modified:
pojo/branches/2.1/pom.xml
Log:
prepare for CR4
Modified: pojo/branches/2.1/pom.xml
===================================================================
--- pojo/branches/2.1/pom.xml 2008-01-21 22:31:27 UTC (rev 5172)
+++ pojo/branches/2.1/pom.xml 2008-01-21 22:51:17 UTC (rev 5173)
@@ -4,8 +4,8 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
- <jbosscache-pojo-version>2.1.0.CR3</jbosscache-pojo-version>
- <jbosscache-core-version>2.1.0.CR3</jbosscache-core-version>
+ <jbosscache-pojo-version>2.1.0.CR4</jbosscache-pojo-version>
+ <jbosscache-core-version>2.1.0.CR4</jbosscache-core-version>
<jboss.aop.version>2.0.0.CR3</jboss.aop.version>
</properties>
<parent>
16 years, 11 months
JBoss Cache SVN: r5172 - in pojo/trunk/src: main/java/org/jboss/cache/pojo/impl and 1 other directories.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2008-01-21 17:31:27 -0500 (Mon, 21 Jan 2008)
New Revision: 5172
Modified:
pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java
pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java
pojo/trunk/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java
Log:
Merge 5170 from branches/2.1
Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java 2008-01-21 22:31:12 UTC (rev 5171)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java 2008-01-21 22:31:27 UTC (rev 5172)
@@ -47,4 +47,10 @@
* @param gravitate true if gravitation should be triggered on cache-miss, false if gravitation should not be triggered
*/
public void setGravitationEnabled(boolean gravitate);
+
+ /**
+ * Clears all thread settings stored on this context. After invoked, defaults will be returned. This will also reclaim
+ * any memory used to store this thread's settings.
+ */
+ public void clear();
}
\ No newline at end of file
Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java 2008-01-21 22:31:12 UTC (rev 5171)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java 2008-01-21 22:31:27 UTC (rev 5172)
@@ -9,6 +9,7 @@
// Every cache instance gets it's own configuration
// An array is used to conserve memory usage since reclamation is slow with TLs, and prevent CL leaks
+ // To further reduce leaks, allocation should be lazily initialized
// In the future, if we get multiple booleans, use bitwise operations on an integer
// as the first entry
private final ThreadLocal<Object[]> state = new ThreadLocal<Object[]>()
@@ -16,7 +17,7 @@
@Override
protected Object[] initialValue()
{
- return new Object[] {GRAVITATE_DEFAULT};
+ return null;
}
};
@@ -31,7 +32,8 @@
*/
public boolean isGravitationEnabled()
{
- return (Boolean) state.get()[GRAVITATE];
+ Object[] values = state.get();
+ return values == null ? GRAVITATE_DEFAULT : (Boolean) values[GRAVITATE];
}
/**
@@ -40,7 +42,24 @@
* @param gravitate true if gravitation should be triggered on cache-miss, false if gravitation should not be triggered
*/
public void setGravitationEnabled(boolean gravitate)
+ {
+ Object[] values = state.get();
+ if (values == null)
+ {
+ // Don't initialize if this is the default
+ if (gravitate == GRAVITATE_DEFAULT)
+ return;
+
+ state.set(new Object[] {gravitate});
+ }
+ else
+ {
+ values[GRAVITATE] = gravitate;
+ }
+ }
+
+ public void clear()
{
- state.get()[GRAVITATE] = gravitate;
+ state.remove();
}
-}
+}
\ No newline at end of file
Modified: pojo/trunk/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java 2008-01-21 22:31:12 UTC (rev 5171)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java 2008-01-21 22:31:27 UTC (rev 5172)
@@ -23,28 +23,20 @@
package org.jboss.cache.pojo;
import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertNotNull;
-import static org.testng.AssertJUnit.assertNull;
-import java.util.List;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.buddyreplication.NextMemberBuddyLocatorConfig;
-import org.jboss.cache.config.BuddyReplicationConfig;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.config.Configuration.CacheMode;
import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
-import org.jboss.cache.pojo.test.Person;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
- * A BuddyReplicatedTest.
+ * Tests the usage and behavior of PojoCacheThreadContext
*
- * @author <a href="brian.stansberry(a)jboss.com">Brian Stansberry</a>
- * @version $Revision: 4717 $
+ * @author Jason T. Greene
*/
@Test(groups = {"functional"})
public class PojoCacheThreadContextTest
@@ -78,6 +70,20 @@
assertEquals(cache1.getThreadContext().isGravitationEnabled(), false);
}
+ public void testClear()
+ {
+ cache1.getThreadContext().setGravitationEnabled(true);
+ cache.getThreadContext().setGravitationEnabled(true);
+
+ assertEquals(cache.getThreadContext().isGravitationEnabled(), true);
+ assertEquals(cache1.getThreadContext().isGravitationEnabled(), true);
+
+ cache1.getThreadContext().clear();
+
+ assertEquals(cache.getThreadContext().isGravitationEnabled(), true);
+ assertEquals(cache1.getThreadContext().isGravitationEnabled(), false);
+ }
+
private class TestThread extends Thread
{
public volatile Throwable t;
16 years, 11 months
JBoss Cache SVN: r5171 - benchmarks/benchmark-fwk/trunk/conf.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2008-01-21 17:31:12 -0500 (Mon, 21 Jan 2008)
New Revision: 5171
Modified:
benchmarks/benchmark-fwk/trunk/conf/cachebench.xml
Log:
added script to starup cluster
Modified: benchmarks/benchmark-fwk/trunk/conf/cachebench.xml
===================================================================
--- benchmarks/benchmark-fwk/trunk/conf/cachebench.xml 2008-01-21 22:30:40 UTC (rev 5170)
+++ benchmarks/benchmark-fwk/trunk/conf/cachebench.xml 2008-01-21 22:31:12 UTC (rev 5171)
@@ -95,7 +95,7 @@
own report generators such as XML generators, graphic generators, etc
-->
<!-- The CSV report generated can be plugged in to a spreadsheet to generate graphs. If 'outputFile is set to
- '-generic-' then the name would be generated as follows: 'performance-<nodeIndeInCluster>.csv' -->
+ '-generic-' then the name would be generated as follows: 'performance-<nodeIndexInCluster>.csv' -->
<report outputFile="-generic-" generator="org.cachebench.reportgenerators.ClusterReportGenerator"/>
</cachebench>
16 years, 11 months
JBoss Cache SVN: r5170 - in pojo/branches/2.1/src: main/java/org/jboss/cache/pojo/impl and 1 other directories.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2008-01-21 17:30:40 -0500 (Mon, 21 Jan 2008)
New Revision: 5170
Modified:
pojo/branches/2.1/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java
pojo/branches/2.1/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java
pojo/branches/2.1/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java
Log:
Further reduce memory allocation used by thread context with lazy loading
Add clear() to the API which is a combined free + reset
Modified: pojo/branches/2.1/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java
===================================================================
--- pojo/branches/2.1/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java 2008-01-21 20:29:45 UTC (rev 5169)
+++ pojo/branches/2.1/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java 2008-01-21 22:30:40 UTC (rev 5170)
@@ -47,4 +47,10 @@
* @param gravitate true if gravitation should be triggered on cache-miss, false if gravitation should not be triggered
*/
public void setGravitationEnabled(boolean gravitate);
+
+ /**
+ * Clears all thread settings stored on this context. After invoked, defaults will be returned. This will also reclaim
+ * any memory used to store this thread's settings.
+ */
+ public void clear();
}
\ No newline at end of file
Modified: pojo/branches/2.1/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java
===================================================================
--- pojo/branches/2.1/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java 2008-01-21 20:29:45 UTC (rev 5169)
+++ pojo/branches/2.1/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java 2008-01-21 22:30:40 UTC (rev 5170)
@@ -9,6 +9,7 @@
// Every cache instance gets it's own configuration
// An array is used to conserve memory usage since reclamation is slow with TLs, and prevent CL leaks
+ // To further reduce leaks, allocation should be lazily initialized
// In the future, if we get multiple booleans, use bitwise operations on an integer
// as the first entry
private final ThreadLocal<Object[]> state = new ThreadLocal<Object[]>()
@@ -16,7 +17,7 @@
@Override
protected Object[] initialValue()
{
- return new Object[] {GRAVITATE_DEFAULT};
+ return null;
}
};
@@ -31,7 +32,8 @@
*/
public boolean isGravitationEnabled()
{
- return (Boolean) state.get()[GRAVITATE];
+ Object[] values = state.get();
+ return values == null ? GRAVITATE_DEFAULT : (Boolean) values[GRAVITATE];
}
/**
@@ -40,7 +42,24 @@
* @param gravitate true if gravitation should be triggered on cache-miss, false if gravitation should not be triggered
*/
public void setGravitationEnabled(boolean gravitate)
+ {
+ Object[] values = state.get();
+ if (values == null)
+ {
+ // Don't initialize if this is the default
+ if (gravitate == GRAVITATE_DEFAULT)
+ return;
+
+ state.set(new Object[] {gravitate});
+ }
+ else
+ {
+ values[GRAVITATE] = gravitate;
+ }
+ }
+
+ public void clear()
{
- state.get()[GRAVITATE] = gravitate;
+ state.remove();
}
-}
+}
\ No newline at end of file
Modified: pojo/branches/2.1/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java
===================================================================
--- pojo/branches/2.1/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java 2008-01-21 20:29:45 UTC (rev 5169)
+++ pojo/branches/2.1/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java 2008-01-21 22:30:40 UTC (rev 5170)
@@ -23,28 +23,20 @@
package org.jboss.cache.pojo;
import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertNotNull;
-import static org.testng.AssertJUnit.assertNull;
-import java.util.List;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.buddyreplication.NextMemberBuddyLocatorConfig;
-import org.jboss.cache.config.BuddyReplicationConfig;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.config.Configuration.CacheMode;
import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
-import org.jboss.cache.pojo.test.Person;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
- * A BuddyReplicatedTest.
+ * Tests the usage and behavior of PojoCacheThreadContext
*
- * @author <a href="brian.stansberry(a)jboss.com">Brian Stansberry</a>
- * @version $Revision: 4717 $
+ * @author Jason T. Greene
*/
@Test(groups = {"functional"})
public class PojoCacheThreadContextTest
@@ -78,6 +70,20 @@
assertEquals(cache1.getThreadContext().isGravitationEnabled(), false);
}
+ public void testClear()
+ {
+ cache1.getThreadContext().setGravitationEnabled(true);
+ cache.getThreadContext().setGravitationEnabled(true);
+
+ assertEquals(cache.getThreadContext().isGravitationEnabled(), true);
+ assertEquals(cache1.getThreadContext().isGravitationEnabled(), true);
+
+ cache1.getThreadContext().clear();
+
+ assertEquals(cache.getThreadContext().isGravitationEnabled(), true);
+ assertEquals(cache1.getThreadContext().isGravitationEnabled(), false);
+ }
+
private class TestThread extends Thread
{
public volatile Throwable t;
16 years, 11 months
JBoss Cache SVN: r5169 - in benchmarks/benchmark-fwk/trunk: doc and 1 other directory.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2008-01-21 15:29:45 -0500 (Mon, 21 Jan 2008)
New Revision: 5169
Added:
benchmarks/benchmark-fwk/trunk/cluster.sh
Modified:
benchmarks/benchmark-fwk/trunk/doc/TODO.txt
Log:
added script to starup cluster
Added: benchmarks/benchmark-fwk/trunk/cluster.sh
===================================================================
--- benchmarks/benchmark-fwk/trunk/cluster.sh (rev 0)
+++ benchmarks/benchmark-fwk/trunk/cluster.sh 2008-01-21 20:29:45 UTC (rev 5169)
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+CACHE_DIST=${1}
+NUM_SERVERS=${2}
+COMMAND=start
+
+SERVER_POSTFIX="qa.atl.jboss.com"
+SERVERS=( cluster01 cluster02 cluster03 cluster04 cluster05 cluster06 cluster07 cluster08 cluster09 cluster10 )
+
+CACHE_BENCHMARK_HOME=`pwd`/code/cache-bench-fwk
+echo "Using cache benchmark home: $CACHE_BENCHMARK_HOME"
+
+case $COMMAND in
+ start)
+ for ((idx=0; idx < NUM_SERVERS ; idx++))
+ do
+ server="${SERVERS[idx]}"
+ echo "jboss: Startup CacheBenchmarkFramework@$server"
+ ssh $server.$SERVER_POSTFIX "cd ${CACHE_BENCHMARK_HOME} && ./runNode.sh &"
+ sleep 5
+ done
+ ;;
+ stop)
+ echo "stop not implemented yet"
+ ;;
+ *)
+ echo "Usage: $0 [start] CACHE_DIST NUM_SERVERS"
+ ;;
+esac
Modified: benchmarks/benchmark-fwk/trunk/doc/TODO.txt
===================================================================
--- benchmarks/benchmark-fwk/trunk/doc/TODO.txt 2008-01-21 17:28:13 UTC (rev 5168)
+++ benchmarks/benchmark-fwk/trunk/doc/TODO.txt 2008-01-21 20:29:45 UTC (rev 5169)
@@ -1,4 +1,5 @@
1) delegate the build of specific products to the cache-products/specific-product. Also
2) make the replication test to run BEFORE warmup
3) conf/config.xml sample size is test specific, move it to the test that uses it rather than having it in the cachebench element
-4) add a target for generating javadoc
+4) add a ant target for generating javadoc
+5) useful: add email notification on any step's failure or success so that a user will be notified whenever needed
16 years, 11 months
JBoss Cache SVN: r5168 - benchmarks/benchmark-fwk/tags.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2008-01-21 12:28:13 -0500 (Mon, 21 Jan 2008)
New Revision: 5168
Added:
benchmarks/benchmark-fwk/tags/bench_JBC210cr3_tc250/
Log:
made a copy
Copied: benchmarks/benchmark-fwk/tags/bench_JBC210cr3_tc250 (from rev 5167, benchmarks/benchmark-fwk/trunk)
16 years, 11 months