JBoss Cache SVN: r6194 - core/trunk.
by jbosscache-commits@lists.jboss.org
Author: bstansberry(a)jboss.com
Date: 2008-07-07 15:41:29 -0400 (Mon, 07 Jul 2008)
New Revision: 6194
Modified:
core/trunk/pom.xml
Log:
[JBCACHE-1387] Update dependencies in JBossAS profile
Modified: core/trunk/pom.xml
===================================================================
--- core/trunk/pom.xml 2008-07-07 19:38:22 UTC (rev 6193)
+++ core/trunk/pom.xml 2008-07-07 19:41:29 UTC (rev 6194)
@@ -30,6 +30,8 @@
<version>2.6.2</version>
</dependency>
+ <!-- For the JTA 1.1 API; consuming projects can safely
+ exclude this and replace with any valid source of this API -->
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
@@ -416,17 +418,18 @@
<dependency>
<groupId>jgroups</groupId>
<artifactId>jgroups</artifactId>
- <version>2.6.2</version>
+ <version>2.6.3.GA</version>
</dependency>
+ <!-- Replaces javax.transaction/jta -->
<dependency>
<groupId>org.jboss.javaee</groupId>
<artifactId>jboss-javaee</artifactId>
- <version>5.0.0.Beta3Update1</version>
+ <version>5.0.0.CR1</version>
</dependency>
<dependency>
<groupId>org.jboss</groupId>
<artifactId>jboss-common-core</artifactId>
- <version>2.2.4.GA</version>
+ <version>2.2.7.GA</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
@@ -436,7 +439,7 @@
<dependency>
<groupId>org.jboss.transaction</groupId>
<artifactId>jboss-jta</artifactId>
- <version>4.3.0.BETA2</version>
+ <version>4.3.0.GA</version>
<scope>test</scope>
</dependency>
</dependencies>
16 years, 6 months
JBoss Cache SVN: r6193 - in core/trunk/src: main/java/org/jboss/cache/commands/legacy/write and 9 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-07-07 15:38:22 -0400 (Mon, 07 Jul 2008)
New Revision: 6193
Added:
core/trunk/src/test/java/org/jboss/cache/api/mvcc/NodeMoveMvccTestBase.java
Modified:
core/trunk/src/main/java/org/jboss/cache/Cache.java
core/trunk/src/main/java/org/jboss/cache/Fqn.java
core/trunk/src/main/java/org/jboss/cache/commands/legacy/write/PessMoveCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/MoveCommand.java
core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java
core/trunk/src/main/java/org/jboss/cache/mvcc/NodeReference.java
core/trunk/src/test/java/org/jboss/cache/FqnTest.java
core/trunk/src/test/java/org/jboss/cache/api/NodeMoveAPITest.java
core/trunk/src/test/java/org/jboss/cache/api/mvcc/read_committed/NodeMoveMvccTest.java
core/trunk/src/test/java/org/jboss/cache/api/mvcc/repeatable_read/NodeMoveMvccTest.java
core/trunk/src/test/java/org/jboss/cache/api/optimistic/NodeMoveOptimisticTest.java
Log:
Improved various mvcc move implementation
Modified: core/trunk/src/main/java/org/jboss/cache/Cache.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/Cache.java 2008-07-07 19:34:48 UTC (rev 6192)
+++ core/trunk/src/main/java/org/jboss/cache/Cache.java 2008-07-07 19:38:22 UTC (rev 6193)
@@ -419,6 +419,13 @@
* /a/e
* </pre>
* No-op if the node to be moved is the root node.
+ * <p/>
+ * <b>Note</b>: As of 3.0.0 and when using MVCC locking, more specific behaviour is defined as follows:
+ * <ul>
+ * <li>A no-op if the node is moved unto itself. E.g., <tt>move(fqn, fqn.getParent())</tt> will not do anything.</li>
+ * <li>If a target node does not exist it will be created silently, to be more consistent with other APIs such as <tt>put()</tt> on a nonexistent node.</li>
+ * <li>If the source node does not exist this is a no-op, to be more consistent with other APIs such as <tt>get()</tt> on a nonexistent node.</li>
+ * </ul>
*
* @param nodeToMove the Fqn of the node to move.
* @param newParent new location under which to attach the node being moved.
Modified: core/trunk/src/main/java/org/jboss/cache/Fqn.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/Fqn.java 2008-07-07 19:34:48 UTC (rev 6192)
+++ core/trunk/src/main/java/org/jboss/cache/Fqn.java 2008-07-07 19:38:22 UTC (rev 6193)
@@ -670,4 +670,18 @@
{
return FqnComparator.INSTANCE.compare(this, Fqn);
}
+
+ /**
+ * Creates a new Fqn whose ancestor has been replaced with the new ancestor passed in.
+ *
+ * @param newAncestor
+ * @return a new Fqn
+ */
+ public Fqn replaceAncestor(Fqn oldAncestor, Fqn newAncestor)
+ {
+ if (!isChildOf(oldAncestor))
+ throw new IllegalArgumentException("Old ancestor must be an ancestor of the current Fqn!");
+ Fqn subFqn = this.getSubFqn(oldAncestor.size(), size());
+ return Fqn.fromRelativeFqn(newAncestor, subFqn);
+ }
}
\ No newline at end of file
Modified: core/trunk/src/main/java/org/jboss/cache/commands/legacy/write/PessMoveCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/legacy/write/PessMoveCommand.java 2008-07-07 19:34:48 UTC (rev 6192)
+++ core/trunk/src/main/java/org/jboss/cache/commands/legacy/write/PessMoveCommand.java 2008-07-07 19:38:22 UTC (rev 6193)
@@ -1,8 +1,11 @@
package org.jboss.cache.commands.legacy.write;
import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeNotExistsException;
+import org.jboss.cache.NodeSPI;
import org.jboss.cache.commands.legacy.ReversibleCommand;
import org.jboss.cache.commands.write.MoveCommand;
+import org.jboss.cache.invocation.InvocationContext;
/**
* A version of {@link org.jboss.cache.commands.write.MoveCommand} which can be rolled back, for use with
@@ -22,6 +25,65 @@
super(from, to);
}
+ /**
+ * Moves a node, from <tt>fqn</tt> to <tt>to</tt>, and returns null.
+ *
+ * @param ctx invocation context
+ * @return null
+ */
+ @Override
+ public Object perform(InvocationContext ctx)
+ {
+ move(fqn, to, false, ctx);
+ return null;
+ }
+
+ private void adjustFqn(NodeSPI node, Fqn newBase)
+ {
+ Fqn newFqn = Fqn.fromRelativeElements(newBase, node.getFqn().getLastElement());
+ node.setFqn(newFqn);
+ }
+
+ private void move(Fqn toMoveFqn, Fqn newParentFqn, boolean skipNotifications, InvocationContext ctx)
+ {
+ // the actual move algorithm.
+ // ctx *could* be null if this is a rollback!!! Sucks big time.
+ NodeSPI newParent = ctx == null ? dataContainer.peek(newParentFqn) : ctx.lookUpNode(newParentFqn);
+ if (newParent == null || newParent.isDeleted())
+ {
+ throw new NodeNotExistsException("New parent node " + newParentFqn + " does not exist when attempting to move node!!");
+ }
+
+ // ctx *could* be null if this is a rollback!!! Sucks big time.
+ NodeSPI node = ctx == null ? dataContainer.peek(toMoveFqn) : ctx.lookUpNode(toMoveFqn);
+
+ if (node == null || node.isDeleted())
+ {
+ throw new NodeNotExistsException("Node " + toMoveFqn + " does not exist when attempting to move node!!");
+ }
+
+ if (trace) log.trace("Moving " + fqn + " to sit under " + to);
+
+ NodeSPI oldParent = node.getParentDirect();
+ Object nodeName = toMoveFqn.getLastElement();
+
+ // now that we have the parent and target nodes:
+ // first correct the pointers at the pruning point
+ oldParent.removeChildDirect(nodeName);
+ newParent.addChild(nodeName, node);
+ // parent pointer is calculated on the fly using Fqns.
+
+ // notify
+ if (!skipNotifications)
+ notifier.notifyNodeMoved(toMoveFqn, Fqn.fromRelativeElements(newParentFqn, toMoveFqn.getLastElement()), true, ctx);
+
+ // now adjust Fqns of node and all children.
+ adjustFqn(node, newParent.getFqn());
+
+ if (!skipNotifications)
+ notifier.notifyNodeMoved(toMoveFqn, Fqn.fromRelativeElements(newParentFqn, toMoveFqn.getLastElement()), false, ctx);
+ }
+
public void rollback()
{
move(Fqn.fromRelativeElements(to, fqn.getLastElement()), fqn.getParent(), true, null);
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/MoveCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/MoveCommand.java 2008-07-07 19:34:48 UTC (rev 6192)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/MoveCommand.java 2008-07-07 19:38:22 UTC (rev 6193)
@@ -4,7 +4,6 @@
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.DataContainer;
import org.jboss.cache.Fqn;
-import org.jboss.cache.NodeNotExistsException;
import org.jboss.cache.NodeSPI;
import org.jboss.cache.commands.Visitor;
import org.jboss.cache.commands.WriteCommand;
@@ -13,21 +12,22 @@
import org.jboss.cache.notifications.Notifier;
import org.jboss.cache.transaction.GlobalTransaction;
+import java.util.Map;
+
/**
* Implements functionality defined by {@link org.jboss.cache.Cache#move(org.jboss.cache.Fqn, org.jboss.cache.Fqn)}
*
* @author Mircea.Markus(a)jboss.com
* @since 2.2
*/
-// TODO: 2.2.0: Make sure this is properly intercepted, i.e., locked and loaded!!
public class MoveCommand extends AbstractDataCommand implements WriteCommand
{
public static final int METHOD_ID = 36;
- private static final Log log = LogFactory.getLog(MoveCommand.class);
- private static final boolean trace = log.isTraceEnabled();
+ protected static final Log log = LogFactory.getLog(MoveCommand.class);
+ protected static final boolean trace = log.isTraceEnabled();
/* dependencies */
- private Notifier notifier;
+ protected Notifier notifier;
/* params */
protected Fqn to;
@@ -67,59 +67,57 @@
*/
public Object perform(InvocationContext ctx)
{
- move(fqn, to, false, ctx);
- return null;
- }
-
- private void adjustFqn(NodeSPI node, Fqn newBase)
- {
- Fqn newFqn = Fqn.fromRelativeElements(newBase, node.getFqn().getLastElement());
- node.setFqn(newFqn);
- }
-
- public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable
- {
- return visitor.visitMoveCommand(ctx, this);
- }
-
- protected void move(Fqn toMoveFqn, Fqn newParentFqn, boolean skipNotifications, InvocationContext ctx)
- {
- // the actual move algorithm.
- // ctx *could* be null if this is a rollback!!! Sucks big time.
- NodeSPI newParent = ctx == null ? dataContainer.peek(newParentFqn) : ctx.lookUpNode(newParentFqn);
- if (newParent == null || newParent.isDeleted())
+ if (to.equals(fqn.getParent()))
{
- throw new NodeNotExistsException("New parent node " + newParentFqn + " does not exist when attempting to move node!!");
+ if (log.isDebugEnabled()) log.debug("Attempting to move " + fqn + " onto itself. Nothing to do.");
+ return null;
}
- // ctx *could* be null if this is a rollback!!! Sucks big time.
- NodeSPI node = ctx == null ? dataContainer.peek(toMoveFqn) : ctx.lookUpNode(toMoveFqn);
+ NodeSPI node = ctx.lookUpNode(fqn);
if (node == null || node.isDeleted())
{
- throw new NodeNotExistsException("Node " + toMoveFqn + " does not exist when attempting to move node!!");
+ if (trace) log.trace("Node " + fqn + " does not exist when attempting to move node! Not doing anything.");
+ return null;
}
if (trace) log.trace("Moving " + fqn + " to sit under " + to);
- NodeSPI oldParent = node.getParentDirect();
- Object nodeName = toMoveFqn.getLastElement();
+ // the actual move algorithm.
+ NodeSPI newNode = ctx.lookUpNode(Fqn.fromRelativeElements(to, fqn.getLastElement()));
+ Fqn newNodeFqn = newNode.getFqn();
- // now that we have the parent and target nodes:
- // first correct the pointers at the pruning point
- oldParent.removeChildDirect(nodeName);
- newParent.addChild(nodeName, node);
- // parent pointer is calculated on the fly using Fqns.
+ // at this stage all child node objects we need have been created and are available in the ctx.
+ // we just need to mark old ones as deleted, new ones as created, and move data across.
+ notifier.notifyNodeMoved(fqn, newNodeFqn, true, ctx);
+ moveRecursively(node, newNode, ctx);
+ notifier.notifyNodeMoved(fqn, newNodeFqn, false, ctx);
+ return null;
+ }
- // notify
- if (!skipNotifications)
- notifier.notifyNodeMoved(toMoveFqn, Fqn.fromRelativeElements(newParentFqn, toMoveFqn.getLastElement()), true, ctx);
+ private void moveRecursively(NodeSPI oldNode, NodeSPI newNode, InvocationContext ctx)
+ {
+ if (trace) log.trace("Moving " + oldNode.getFqn() + " to " + newNode.getFqn());
+ // start deep.
+ Map<Object, NodeSPI> children = oldNode.getChildrenMapDirect();
+ if (children != null && !children.isEmpty())
+ {
+ for (NodeSPI child : children.values())
+ {
+ Fqn childFqn = child.getFqn();
+ Fqn newChildFqn = childFqn.replaceAncestor(oldNode.getFqn(), newNode.getFqn());
+ moveRecursively(ctx.lookUpNode(childFqn), ctx.lookUpNode(newChildFqn), ctx);
+ }
+ }
- // now adjust Fqns of node and all children.
- adjustFqn(node, newParent.getFqn());
+ // now swap the data for the current node.
+ newNode.putAllDirect(oldNode.getDataDirect());
+ oldNode.markAsDeleted(true);
+ }
- if (!skipNotifications)
- notifier.notifyNodeMoved(toMoveFqn, Fqn.fromRelativeElements(newParentFqn, toMoveFqn.getLastElement()), false, ctx);
+ public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable
+ {
+ return visitor.visitMoveCommand(ctx, this);
}
public Fqn getTo()
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java 2008-07-07 19:34:48 UTC (rev 6192)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java 2008-07-07 19:38:22 UTC (rev 6193)
@@ -298,16 +298,23 @@
{
// nodes we need to get WLs for:
// node we are moving FROM (and it's parent and children.) Same as removeNode.
- List<Fqn> children = addNodeAndParentForRemoval(ctx, command.getFqn(), true);
+ List<Fqn> nodeAndChildren = addNodeAndParentForRemoval(ctx, command.getFqn(), true);
+ Fqn newParent = command.getTo();
+ Fqn oldParent = command.getFqn().getParent();
+
// now lock the new parent.
- getWrappedNode(ctx, command.getTo(), true, true, false);
+ getWrappedNode(ctx, newParent, true, true, false);
- // the children list contains all child nodes, including the node itself.
- // now obtain locks on the new places these children will occupy.
- for (Fqn f : children)
+ if (!oldParent.equals(newParent) && nodeAndChildren != null)
{
- getWrappedNode(ctx, Fqn.fromRelativeFqn(command.getTo(), f), true, true, true);
+ // the nodeAndChildren list contains all child nodes, including the node itself.
+ // now obtain locks on the new places these new nodes will occupy.
+ for (Fqn f : nodeAndChildren)
+ {
+ Fqn newChildFqn = f.replaceAncestor(oldParent, newParent);
+ getWrappedNode(ctx, newChildFqn, true, true, true);
+ }
}
// now pass up the chain.
Modified: core/trunk/src/main/java/org/jboss/cache/mvcc/NodeReference.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/mvcc/NodeReference.java 2008-07-07 19:34:48 UTC (rev 6192)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/NodeReference.java 2008-07-07 19:38:22 UTC (rev 6193)
@@ -294,4 +294,23 @@
"delegate=" + delegate +
'}';
}
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ NodeReference that = (NodeReference) o;
+
+ if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return (delegate != null ? delegate.hashCode() : 0);
+ }
}
Modified: core/trunk/src/test/java/org/jboss/cache/FqnTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/FqnTest.java 2008-07-07 19:34:48 UTC (rev 6192)
+++ core/trunk/src/test/java/org/jboss/cache/FqnTest.java 2008-07-07 19:38:22 UTC (rev 6193)
@@ -432,6 +432,24 @@
System.out.println("-- " + msg);
}
+ public void testReplacingDirectAncestor()
+ {
+ Fqn fqn = Fqn.fromString("/a/b/c");
+ Fqn newParent = Fqn.fromString("/hot/dog");
+ Fqn expectedNewChild = Fqn.fromString("/hot/dog/c");
+
+ assert expectedNewChild.equals(fqn.replaceAncestor(fqn.getParent(), newParent));
+ }
+
+ public void testReplacingindirectAncestor()
+ {
+ Fqn fqn = Fqn.fromString("/a/b/c");
+ Fqn newParent = Fqn.fromString("/hot/dog");
+ Fqn expectedNewChild = Fqn.fromString("/hot/dog/b/c");
+
+ assert expectedNewChild.equals(fqn.replaceAncestor(fqn.getParent().getParent(), newParent));
+ }
+
public void testDifferentFactories()
{
Fqn[] fqns = new Fqn[7];
Modified: core/trunk/src/test/java/org/jboss/cache/api/NodeMoveAPITest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/NodeMoveAPITest.java 2008-07-07 19:34:48 UTC (rev 6192)
+++ core/trunk/src/test/java/org/jboss/cache/api/NodeMoveAPITest.java 2008-07-07 19:38:22 UTC (rev 6193)
@@ -69,7 +69,6 @@
// to be overridden
}
- @Test(groups = {"functional"})
public void testBasicMove()
{
nodeA = rootNode.addChild(A);
@@ -134,7 +133,6 @@
return (Node<Object, Object>) node;
}
- @Test(groups = {"functional"})
public void testMoveWithChildren()
{
nodeA = rootNode.addChild(A);
@@ -203,7 +201,6 @@
assertEquals(nodeD, nodeE.getParent());
}
- @Test(groups = {"functional"})
public void testTxCommit() throws Exception
{
nodeA = rootNode.addChild(A);
@@ -231,7 +228,6 @@
assertTrue(nodeA.getChildren().isEmpty());
}
- @Test(groups = {"functional"})
public void testTxRollback() throws Exception
{
nodeA = rootNode.addChild(A);
@@ -248,7 +244,7 @@
cache.move(nodeB.getFqn(), Fqn.ROOT);
// need to think of a way to test the same with optimistically locked nodes
- if (!isOptimistic())
+ if (nodeLockingScheme == NodeLockingScheme.PESSIMISTIC)
{
assertEquals(rootNode, nodeA.getParent());
assertEquals(rootNode, nodeB.getParent());
@@ -270,25 +266,21 @@
assertEquals(nodeB, nodeA.getChildren().iterator().next());
}
- @Test(groups = {"functional"})
public void testWithCacheloaders() throws Exception
{
doCacheLoaderTest(false, false);
}
- @Test(groups = {"functional"})
public void testWithPassivation() throws Exception
{
doCacheLoaderTest(true, false);
}
- @Test(groups = {"functional"})
public void testWithCacheloadersTx() throws Exception
{
doCacheLoaderTest(false, true);
}
- @Test(groups = {"functional"})
public void testWithPassivationTx() throws Exception
{
doCacheLoaderTest(true, true);
@@ -296,7 +288,6 @@
protected void doCacheLoaderTest(boolean pasv, boolean useTx) throws Exception
{
-// cache.stop();
cache.destroy();
cache.getConfiguration().setCacheLoaderConfig(getSingleCacheLoaderConfig(pasv, "/", DummyInMemoryCacheLoader.class.getName(), null, false, false, false, false));
cache.start();
@@ -372,27 +363,26 @@
}
- @Test(groups = {"functional"})
public void testLocksDeepMove() throws Exception
{
nodeA = rootNode.addChild(A);
nodeB = nodeA.addChild(B);
nodeD = nodeB.addChild(D);
nodeC = rootNode.addChild(C);
+ nodeE = nodeC.addChild(E);
assertEquals(0, cache.getNumberOfLocksHeld());
tm.begin();
cache.move(nodeC.getFqn(), nodeB.getFqn());
- // nodeC should have a RL, nodeA should have a RL, nodeB should have a WL, nodeD should have a WL
- assertEquals("ROOT should have a RL, nodeC should have a RL, nodeA should have a RL, nodeB should have a WL, nodeD should have a WL", 5, cache.getNumberOfLocksHeld());
+ checkLocksDeep();
+
tm.commit();
assertEquals(0, cache.getNumberOfLocksHeld());
}
- @Test(groups = {"functional"})
public void testLocks() throws Exception
{
nodeA = rootNode.addChild(A);
@@ -414,17 +404,18 @@
assertEquals("ROOT should have a RL, nodeC should have a RL, nodeA should have a RL, nodeB should have a WL", 4, cache.getNumberOfLocksHeld());
}
+ protected void checkLocksDeep()
+ {
+ assertEquals("ROOT should have a RL, nodeC should have a RL, nodeA should have a RL, nodeB should have a WL, nodeD should have a WL", 6, cache.getNumberOfLocksHeld());
+ }
+
protected void assertNoLocks()
{
assertEquals(0, cache.getNumberOfLocksHeld());
}
- @Test(groups = {"functional"})
public void testConcurrency() throws InterruptedException
{
- // FIXME: investigate intermittent failure when in isOptimistic() mode.
- if (isOptimistic()) return;
-
final int N = 3;// number of threads
final int loops = 1 << 6;// number of loops
// tests a tree structure as such:
@@ -536,7 +527,6 @@
assertFalse("Should have only found y once", found_y_again);
}
- @Test(groups = {"functional"})
public void testMoveInSamePlace()
{
final Fqn<String> FQN_X = Fqn.fromString("/x");
@@ -546,6 +536,8 @@
assertEquals(aNode.getChildren().size(), 1);
cache.move(xNode.getFqn(), aNode.getFqn());
assertEquals(aNode.getChildren().size(), 1);
+
+ assert 0 == cache.getNumberOfLocksHeld();
}
protected CacheLoaderConfig getSingleCacheLoaderConfig(boolean passivation, String preload, String cacheloaderClass, String properties, boolean async, boolean fetchPersistentState, boolean shared, boolean purgeOnStartup) throws Exception
@@ -569,6 +561,6 @@
protected boolean isOptimistic()
{
- return nodeLockingScheme == NodeLockingScheme.OPTIMISTIC;
+ return false;
}
}
Added: core/trunk/src/test/java/org/jboss/cache/api/mvcc/NodeMoveMvccTestBase.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/mvcc/NodeMoveMvccTestBase.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/api/mvcc/NodeMoveMvccTestBase.java 2008-07-07 19:38:22 UTC (rev 6193)
@@ -0,0 +1,104 @@
+package org.jboss.cache.api.mvcc;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.api.NodeMoveAPITest;
+import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.jboss.cache.factories.ComponentRegistry;
+import org.jboss.cache.invocation.InvocationContextContainer;
+import org.jboss.cache.lock.LockManager;
+import org.jboss.cache.util.TestingUtil;
+import org.testng.annotations.Test;
+
+@Test(groups = {"functional", "mvcc"})
+public abstract class NodeMoveMvccTestBase extends NodeMoveAPITest
+{
+ Fqn A_B = Fqn.fromRelativeFqn(A, B);
+ Fqn A_B_C = Fqn.fromRelativeFqn(A_B, C);
+ Fqn A_B_C_E = Fqn.fromRelativeFqn(A_B_C, E);
+ Fqn A_B_D = Fqn.fromRelativeFqn(A_B, D);
+ Fqn C_E = Fqn.fromRelativeFqn(C, E);
+ Fqn D_B = Fqn.fromRelativeFqn(D, B);
+ Fqn D_B_C = Fqn.fromRelativeFqn(D_B, C);
+
+
+ public NodeMoveMvccTestBase()
+ {
+ nodeLockingScheme = NodeLockingScheme.MVCC;
+ }
+
+ @Override
+ protected void checkLocks()
+ {
+ ComponentRegistry cr = TestingUtil.extractComponentRegistry(cache);
+ LockManager lm = cr.getComponent(LockManager.class);
+ InvocationContextContainer icc = cr.getComponent(InvocationContextContainer.class);
+
+ LockAssert.assertNotLocked(A, lm, icc);
+ LockAssert.assertNotLocked(Fqn.ROOT, lm, icc);
+ LockAssert.assertLocked(C, lm, icc);
+ LockAssert.assertLocked(A_B, lm, icc);
+ LockAssert.assertLocked(A_B_C, lm, icc);
+ }
+
+ @Override
+ protected void checkLocksDeep()
+ {
+ ComponentRegistry cr = TestingUtil.extractComponentRegistry(cache);
+ LockManager lm = cr.getComponent(LockManager.class);
+ InvocationContextContainer icc = cr.getComponent(InvocationContextContainer.class);
+
+ LockAssert.assertNotLocked(A, lm, icc);
+ LockAssert.assertNotLocked(Fqn.ROOT, lm, icc);
+ LockAssert.assertNotLocked(A_B_D, lm, icc);
+
+ // /a/b, /c, /c/e, /a/b/c and /a/b/c/e should all be locked.
+ LockAssert.assertLocked(A_B, lm, icc);
+ LockAssert.assertLocked(C, lm, icc);
+ LockAssert.assertLocked(C_E, lm, icc);
+ LockAssert.assertLocked(A_B_C, lm, icc);
+ LockAssert.assertLocked(A_B_C_E, lm, icc);
+ }
+
+ @Override
+ protected void assertNoLocks()
+ {
+ ComponentRegistry cr = TestingUtil.extractComponentRegistry(cache);
+ LockManager lm = cr.getComponent(LockManager.class);
+ InvocationContextContainer icc = cr.getComponent(InvocationContextContainer.class);
+ LockAssert.assertNoLocks(lm, icc);
+ }
+
+ public void testNonexistentSource()
+ {
+ cache.put(A_B_C, "k", "v");
+ assert "v".equals(cache.get(A_B_C, "k"));
+ assert 1 == cache.getNode(A_B).getChildren().size();
+ assert cache.getNode(A_B).getChildrenNames().contains(C.getLastElement());
+ assert !cache.getNode(A_B).getChildrenNames().contains(D.getLastElement());
+
+ cache.move(D, A_B);
+
+ assert "v".equals(cache.get(A_B_C, "k"));
+ assert 1 == cache.getNode(A_B).getChildren().size();
+ assert cache.getNode(A_B).getChildrenNames().contains(C.getLastElement());
+ assert !cache.getNode(A_B).getChildrenNames().contains(D.getLastElement());
+ }
+
+ public void testNonexistentTarget()
+ {
+ cache.put(A_B_C, "k", "v");
+ assert "v".equals(cache.get(A_B_C, "k"));
+ assert 1 == cache.getNode(A_B).getChildren().size();
+ assert cache.getNode(A_B).getChildrenNames().contains(C.getLastElement());
+ assert null == cache.getNode(D);
+
+ cache.move(A_B, D);
+
+ assert null == cache.getNode(A_B_C);
+ assert null == cache.getNode(A_B);
+ assert null != cache.getNode(D);
+ assert null != cache.getNode(D_B);
+ assert null != cache.getNode(D_B_C);
+ assert "v".equals(cache.get(D_B_C, "k"));
+ }
+}
Modified: core/trunk/src/test/java/org/jboss/cache/api/mvcc/read_committed/NodeMoveMvccTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/mvcc/read_committed/NodeMoveMvccTest.java 2008-07-07 19:34:48 UTC (rev 6192)
+++ core/trunk/src/test/java/org/jboss/cache/api/mvcc/read_committed/NodeMoveMvccTest.java 2008-07-07 19:38:22 UTC (rev 6193)
@@ -6,52 +6,17 @@
*/
package org.jboss.cache.api.mvcc.read_committed;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.api.NodeMoveAPITest;
-import org.jboss.cache.api.mvcc.LockAssert;
+import org.jboss.cache.api.mvcc.NodeMoveMvccTestBase;
import org.jboss.cache.config.Configuration;
-import org.jboss.cache.config.Configuration.NodeLockingScheme;
-import org.jboss.cache.factories.ComponentRegistry;
-import org.jboss.cache.invocation.InvocationContextContainer;
import org.jboss.cache.lock.IsolationLevel;
-import org.jboss.cache.lock.LockManager;
-import org.jboss.cache.util.TestingUtil;
import org.testng.annotations.Test;
@Test(groups = {"functional", "mvcc"})
-public class NodeMoveMvccTest extends NodeMoveAPITest
+public class NodeMoveMvccTest extends NodeMoveMvccTestBase
{
- public NodeMoveMvccTest()
- {
- nodeLockingScheme = NodeLockingScheme.MVCC;
- }
-
@Override
protected void configure(Configuration c)
{
c.setIsolationLevel(IsolationLevel.READ_COMMITTED);
}
-
- @Override
- protected void checkLocks()
- {
- ComponentRegistry cr = TestingUtil.extractComponentRegistry(cache);
- LockManager lm = cr.getComponent(LockManager.class);
- InvocationContextContainer icc = cr.getComponent(InvocationContextContainer.class);
-
- LockAssert.assertNotLocked(A, lm, icc);
- LockAssert.assertLocked(Fqn.ROOT, lm, icc);
- LockAssert.assertLocked(C, lm, icc);
- LockAssert.assertLocked(Fqn.fromRelativeFqn(A, B), lm, icc);
- LockAssert.assertLocked(Fqn.fromRelativeFqn(B, C), lm, icc);
- }
-
- @Override
- protected void assertNoLocks()
- {
- ComponentRegistry cr = TestingUtil.extractComponentRegistry(cache);
- LockManager lm = cr.getComponent(LockManager.class);
- InvocationContextContainer icc = cr.getComponent(InvocationContextContainer.class);
- LockAssert.assertNoLocks(lm, icc);
- }
}
\ No newline at end of file
Modified: core/trunk/src/test/java/org/jboss/cache/api/mvcc/repeatable_read/NodeMoveMvccTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/mvcc/repeatable_read/NodeMoveMvccTest.java 2008-07-07 19:34:48 UTC (rev 6192)
+++ core/trunk/src/test/java/org/jboss/cache/api/mvcc/repeatable_read/NodeMoveMvccTest.java 2008-07-07 19:38:22 UTC (rev 6193)
@@ -6,52 +6,17 @@
*/
package org.jboss.cache.api.mvcc.repeatable_read;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.api.NodeMoveAPITest;
-import org.jboss.cache.api.mvcc.LockAssert;
+import org.jboss.cache.api.mvcc.NodeMoveMvccTestBase;
import org.jboss.cache.config.Configuration;
-import org.jboss.cache.config.Configuration.NodeLockingScheme;
-import org.jboss.cache.factories.ComponentRegistry;
-import org.jboss.cache.invocation.InvocationContextContainer;
import org.jboss.cache.lock.IsolationLevel;
-import org.jboss.cache.lock.LockManager;
-import org.jboss.cache.util.TestingUtil;
import org.testng.annotations.Test;
@Test(groups = {"functional", "mvcc"})
-public class NodeMoveMvccTest extends NodeMoveAPITest
+public class NodeMoveMvccTest extends NodeMoveMvccTestBase
{
- public NodeMoveMvccTest()
- {
- nodeLockingScheme = NodeLockingScheme.MVCC;
- }
-
@Override
protected void configure(Configuration c)
{
c.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
}
-
- @Override
- protected void checkLocks()
- {
- ComponentRegistry cr = TestingUtil.extractComponentRegistry(cache);
- LockManager lm = cr.getComponent(LockManager.class);
- InvocationContextContainer icc = cr.getComponent(InvocationContextContainer.class);
-
- LockAssert.assertNotLocked(A, lm, icc);
- LockAssert.assertLocked(Fqn.ROOT, lm, icc);
- LockAssert.assertLocked(C, lm, icc);
- LockAssert.assertLocked(Fqn.fromRelativeFqn(A, B), lm, icc);
- LockAssert.assertLocked(Fqn.fromRelativeFqn(Fqn.fromRelativeFqn(A, B), C), lm, icc);
- }
-
- @Override
- protected void assertNoLocks()
- {
- ComponentRegistry cr = TestingUtil.extractComponentRegistry(cache);
- LockManager lm = cr.getComponent(LockManager.class);
- InvocationContextContainer icc = cr.getComponent(InvocationContextContainer.class);
- LockAssert.assertNoLocks(lm, icc);
- }
}
Modified: core/trunk/src/test/java/org/jboss/cache/api/optimistic/NodeMoveOptimisticTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/optimistic/NodeMoveOptimisticTest.java 2008-07-07 19:34:48 UTC (rev 6192)
+++ core/trunk/src/test/java/org/jboss/cache/api/optimistic/NodeMoveOptimisticTest.java 2008-07-07 19:38:22 UTC (rev 6193)
@@ -18,13 +18,27 @@
nodeLockingScheme = NodeLockingScheme.OPTIMISTIC;
}
+ @Override
+ protected boolean isOptimistic()
+ {
+ return true;
+ }
+
+ @Override
public void testLocks()
{
// no op
}
+ @Override
public void testLocksDeepMove()
{
// no op
}
+
+ @Override
+ public void testConcurrency()
+ {
+ // no op
+ }
}
16 years, 6 months
JBoss Cache SVN: r6192 - core/branches/2.2.X.
by jbosscache-commits@lists.jboss.org
Author: bstansberry(a)jboss.com
Date: 2008-07-07 15:34:48 -0400 (Mon, 07 Jul 2008)
New Revision: 6192
Modified:
core/branches/2.2.X/pom.xml
Log:
[JBCACHE-1387] Update dependencies in JBossAS profile
Modified: core/branches/2.2.X/pom.xml
===================================================================
--- core/branches/2.2.X/pom.xml 2008-07-07 19:25:47 UTC (rev 6191)
+++ core/branches/2.2.X/pom.xml 2008-07-07 19:34:48 UTC (rev 6192)
@@ -30,6 +30,8 @@
<version>2.6.2</version>
</dependency>
+ <!-- For the JTA 1.1 API; consuming projects can safely
+ exclude this and replace with any valid source of this API -->
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
@@ -411,22 +413,24 @@
</activation>
<properties>
<jbosscache-core-version>2.2.0-SNAPSHOT-JBossAS</jbosscache-core-version>
+ <defaultTestGroup>functional,unit</defaultTestGroup>
</properties>
<dependencies>
<dependency>
<groupId>jgroups</groupId>
<artifactId>jgroups</artifactId>
- <version>2.6.2</version>
+ <version>2.6.3.GA</version>
</dependency>
+ <!-- Replaces javax.transaction/jta -->
<dependency>
<groupId>org.jboss.javaee</groupId>
<artifactId>jboss-javaee</artifactId>
- <version>5.0.0.Beta3Update1</version>
+ <version>5.0.0.CR1</version>
</dependency>
<dependency>
<groupId>org.jboss</groupId>
<artifactId>jboss-common-core</artifactId>
- <version>2.2.4.GA</version>
+ <version>2.2.7.GA</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
@@ -436,7 +440,7 @@
<dependency>
<groupId>org.jboss.transaction</groupId>
<artifactId>jboss-jta</artifactId>
- <version>4.3.0.BETA2</version>
+ <version>4.3.0.GA</version>
<scope>test</scope>
</dependency>
</dependencies>
16 years, 6 months
JBoss Cache SVN: r6191 - core/branches/2.2.X/src/test/java/org/jboss/cache/marshall.
by jbosscache-commits@lists.jboss.org
Author: galder.zamarreno(a)jboss.com
Date: 2008-07-07 15:25:47 -0400 (Mon, 07 Jul 2008)
New Revision: 6191
Modified:
core/branches/2.2.X/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java
Log:
[JBCACHE-1357] Added @author.
Modified: core/branches/2.2.X/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java
===================================================================
--- core/branches/2.2.X/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java 2008-07-07 19:24:30 UTC (rev 6190)
+++ core/branches/2.2.X/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java 2008-07-07 19:25:47 UTC (rev 6191)
@@ -30,6 +30,7 @@
* not visible to the cache's default classloader.
*
* @author <a href="mailto:brian.stansberry@jboss.org">Brian Stansberry</a>
+ * @author <a href="mailto:galder.zamarreno@jboss.com">Galder Zamarreno</a>
* @since 2.1.0
*/
@Test(groups = "functional")
16 years, 6 months
JBoss Cache SVN: r6190 - core/branches/2.2.X/src/test/java/org/jboss/cache/marshall.
by jbosscache-commits@lists.jboss.org
Author: galder.zamarreno(a)jboss.com
Date: 2008-07-07 15:24:30 -0400 (Mon, 07 Jul 2008)
New Revision: 6190
Modified:
core/branches/2.2.X/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java
Log:
[JBCACHE-1357] Issue not present in 2.2.x but I still added the test case.
Modified: core/branches/2.2.X/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java
===================================================================
--- core/branches/2.2.X/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java 2008-07-07 18:28:33 UTC (rev 6189)
+++ core/branches/2.2.X/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java 2008-07-07 19:24:30 UTC (rev 6190)
@@ -3,6 +3,7 @@
import org.jboss.cache.Cache;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
import org.jboss.cache.Region;
import org.jboss.cache.config.CacheLoaderConfig;
import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
@@ -14,6 +15,7 @@
import org.jboss.cache.loader.FileCacheLoaderConfig;
import org.jboss.cache.util.TestingUtil;
import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -65,7 +67,42 @@
{
cacheLoaderMarshallingTest(true);
}
+
+ public void testLoadNodesAtRootOfRegion() throws Exception
+ {
+ String rootRegionName = "/myregion";
+ String hereFqn = rootRegionName + "/here";
+
+ cache = createCache(true);
+ cache.start();
+ Region r = cache.getRegion(Fqn.fromString(rootRegionName), true);
+ r.registerContextClassLoader(Thread.currentThread().getContextClassLoader());
+ r.activate();
+
+ cache.put(rootRegionName, "a key", "a value");
+ cache.put(hereFqn, "another key", "another value");
+
+ r.deactivate();
+ r.unregisterContextClassLoader();
+
+ cache.stop();
+
+ cache.start();
+
+ r = cache.getRegion(Fqn.fromString(rootRegionName), true);
+ r.registerContextClassLoader(Thread.currentThread().getContextClassLoader());
+ r.activate();
+
+ Node<Object, Object> rootRegionNode = cache.getNode(rootRegionName);
+ Node<Object, Object> hereNode = cache.getNode(hereFqn);
+ assertNotNull(rootRegionNode);
+ assertNotNull(hereNode);
+
+ assertEquals(hereNode.get("another key"), "another value");
+ assertEquals(rootRegionNode.get("a key"), "a value");
+ }
+
private void cacheLoaderMarshallingTest(boolean useRegionBased) throws Exception
{
cache = createCache(useRegionBased);
16 years, 6 months
JBoss Cache SVN: r6189 - core/branches/1.4.X/tests/functional/org/jboss/cache/loader.
by jbosscache-commits@lists.jboss.org
Author: galder.zamarreno(a)jboss.com
Date: 2008-07-07 14:28:33 -0400 (Mon, 07 Jul 2008)
New Revision: 6189
Modified:
core/branches/1.4.X/tests/functional/org/jboss/cache/loader/MarshalledCacheLoaderTest.java
Log:
[JBCACHE-1357] Minor fix on cache loader creation.
Modified: core/branches/1.4.X/tests/functional/org/jboss/cache/loader/MarshalledCacheLoaderTest.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/loader/MarshalledCacheLoaderTest.java 2008-07-07 18:22:43 UTC (rev 6188)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/loader/MarshalledCacheLoaderTest.java 2008-07-07 18:28:33 UTC (rev 6189)
@@ -45,7 +45,7 @@
cache=new TreeCache();
cache.setCacheMode("LOCAL");
cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
- cache.setCacheLoaderConfiguration(getSingleCacheLoaderConfig("true", DummyInMemoryCacheLoader.class.getName(), "", false, true, false));
+ cache.setCacheLoaderConfiguration(getSingleCacheLoaderConfig("", DummyInMemoryCacheLoader.class.getName(), "", false, false, false));
cache.setUseRegionBasedMarshalling(true);
cache.setInactiveOnStartup(true);
cache.startService();
16 years, 6 months
JBoss Cache SVN: r6188 - core/branches/1.4.X/tests/functional/org/jboss/cache/loader.
by jbosscache-commits@lists.jboss.org
Author: galder.zamarreno(a)jboss.com
Date: 2008-07-07 14:22:43 -0400 (Mon, 07 Jul 2008)
New Revision: 6188
Modified:
core/branches/1.4.X/tests/functional/org/jboss/cache/loader/MarshalledCacheLoaderTest.java
Log:
[JBCACHE-1357] Use dummy cache loader instead of file cache loader.
Modified: core/branches/1.4.X/tests/functional/org/jboss/cache/loader/MarshalledCacheLoaderTest.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/loader/MarshalledCacheLoaderTest.java 2008-07-07 18:12:35 UTC (rev 6187)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/loader/MarshalledCacheLoaderTest.java 2008-07-07 18:22:43 UTC (rev 6188)
@@ -45,7 +45,7 @@
cache=new TreeCache();
cache.setCacheMode("LOCAL");
cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
- cache.setCacheLoaderConfiguration(getSingleCacheLoaderConfig("true", "org.jboss.cache.loader.FileCacheLoader", "", false, true, false));
+ cache.setCacheLoaderConfiguration(getSingleCacheLoaderConfig("true", DummyInMemoryCacheLoader.class.getName(), "", false, true, false));
cache.setUseRegionBasedMarshalling(true);
cache.setInactiveOnStartup(true);
cache.startService();
16 years, 6 months
JBoss Cache SVN: r6187 - in core/branches/1.4.X: src/org/jboss/cache/interceptors and 2 other directories.
by jbosscache-commits@lists.jboss.org
Author: galder.zamarreno(a)jboss.com
Date: 2008-07-07 14:12:35 -0400 (Mon, 07 Jul 2008)
New Revision: 6187
Added:
core/branches/1.4.X/tests/functional/org/jboss/cache/loader/MarshalledCacheLoaderTest.java
Modified:
core/branches/1.4.X/src/org/jboss/cache/TreeCache.java
core/branches/1.4.X/src/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
core/branches/1.4.X/src/org/jboss/cache/loader/FileCacheLoader.java
Log:
[JBCACHE-1357] Root region node is now created as UNINITIALIZED.
Modified: core/branches/1.4.X/src/org/jboss/cache/TreeCache.java
===================================================================
--- core/branches/1.4.X/src/org/jboss/cache/TreeCache.java 2008-07-07 14:39:36 UTC (rev 6186)
+++ core/branches/1.4.X/src/org/jboss/cache/TreeCache.java 2008-07-07 18:12:35 UTC (rev 6187)
@@ -100,6 +100,7 @@
* @author <a href="mailto:manik@jboss.org">Manik Surtani (manik(a)jboss.org)</a>
* @author Brian Stansberry
* @author Daniel Huang (dhuang(a)jboss.org)
+ * @author <a href="mailto:galder.zamarreno@jboss.com">Galder Zamarreno</a>
* @version $Id$
* <p/>
* @see <a href="http://labs.jboss.com/portal/jbosscache/docs">JBossCache doc</a>
@@ -2301,6 +2302,9 @@
child = factory.createDataNode(type, name,
subtree.getFqnChild(i + 1),
parent, null, this);
+ // Add uninitialized flag so that data stored at the root of the
+ // region can be loaded/preloaded from the cache loader.
+ child.put(UNINITIALIZED, null);
parent.addChild(name, child);
}
finally
Modified: core/branches/1.4.X/src/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
===================================================================
--- core/branches/1.4.X/src/org/jboss/cache/interceptors/CacheLoaderInterceptor.java 2008-07-07 14:39:36 UTC (rev 6186)
+++ core/branches/1.4.X/src/org/jboss/cache/interceptors/CacheLoaderInterceptor.java 2008-07-07 18:12:35 UTC (rev 6187)
@@ -30,6 +30,7 @@
* Loads nodes that don't exist at the time of the call into memory from the CacheLoader
*
* @author Bela Ban
+ * @author <a href="mailto:galder.zamarreno@jboss.com">Galder Zamarreno</a>
* @version $Id$
*/
public class CacheLoaderInterceptor extends Interceptor implements CacheLoaderInterceptorMBean
@@ -169,9 +170,10 @@
{
DataNode n = cache.peek(fqn);
+ boolean mustLoad = mustLoad(n, key);
if (log.isTraceEnabled())
- log.trace("load element " + fqn + " mustLoad=" + mustLoad(n, key));
- if (mustLoad(n, key))
+ log.trace("load element " + fqn + " mustLoad=" + mustLoad);
+ if (mustLoad)
{
if (initNode)
{
@@ -254,6 +256,11 @@
private boolean mustLoad(DataNode n, Object key)
{
+ if (log.isTraceEnabled())
+ {
+ log.trace("mustLoad called with key=" + key + " and datanode=" + n);
+ }
+
return n == null ||
(n.containsKey(TreeCache.UNINITIALIZED) && (key == null || !n.containsKey(key)));
}
Modified: core/branches/1.4.X/src/org/jboss/cache/loader/FileCacheLoader.java
===================================================================
--- core/branches/1.4.X/src/org/jboss/cache/loader/FileCacheLoader.java 2008-07-07 14:39:36 UTC (rev 6186)
+++ core/branches/1.4.X/src/org/jboss/cache/loader/FileCacheLoader.java 2008-07-07 18:12:35 UTC (rev 6187)
@@ -560,6 +560,10 @@
FileInputStream in = new FileInputStream(child);
MarshalledValueInputStream input = new MarshalledValueInputStream(in);
Map m = (Map) input.readObject();
+ if (log.isTraceEnabled())
+ {
+ log.trace("Read fqn="+ fqn + " from file input stream and returned " + m);
+ }
in.close();
return m;
}
@@ -573,6 +577,10 @@
throw new IOException("Unable to create file: " + child);
FileOutputStream out = new FileOutputStream(child);
ObjectOutputStream output = new ObjectOutputStream(out);
+ if (log.isTraceEnabled())
+ {
+ log.trace("Writing to file output stream: fqn="+ fqn + " modifications=" + attrs);
+ }
output.writeObject(attrs);
out.close();
}
Added: core/branches/1.4.X/tests/functional/org/jboss/cache/loader/MarshalledCacheLoaderTest.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/loader/MarshalledCacheLoaderTest.java (rev 0)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/loader/MarshalledCacheLoaderTest.java 2008-07-07 18:12:35 UTC (rev 6187)
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.cache.loader;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.Node;
+import org.jboss.cache.TreeCache;
+
+/**
+ * Unit test for checking interaction between cache loader and marshalled
+ * regions.
+ *
+ * @author <a href="mailto:galder.zamarreno@jboss.com">Galder Zamarreno</a>
+ */
+public class MarshalledCacheLoaderTest extends AbstractCacheLoaderTestBase
+{
+ private static final Log log = LogFactory.getLog(MarshalledCacheLoaderTest.class);
+
+ private TreeCache cache;
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ cache=new TreeCache();
+ cache.setCacheMode("LOCAL");
+ cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
+ cache.setCacheLoaderConfiguration(getSingleCacheLoaderConfig("true", "org.jboss.cache.loader.FileCacheLoader", "", false, true, false));
+ cache.setUseRegionBasedMarshalling(true);
+ cache.setInactiveOnStartup(true);
+ cache.startService();
+ }
+
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ cache.remove("/");
+ cache.stopService();
+ cache.destroyService();
+ }
+
+ public void testLoadNodesAtRootOfRegion() throws Exception
+ {
+ String rootRegionName = "/myregion";
+ String fqn = rootRegionName + "/here";
+
+ cache.registerClassLoader(rootRegionName, Thread.currentThread().getContextClassLoader());
+ cache.activateRegion(rootRegionName);
+ cache.put(rootRegionName, "a key", "a value");
+ cache.put(fqn, "another key", "another value");
+
+ cache.inactivateRegion(rootRegionName);
+ cache.unregisterClassLoader(rootRegionName);
+
+ cache.stopService();
+ cache.destroyService();
+
+ cache.startService();
+
+ cache.registerClassLoader(rootRegionName, Thread.currentThread().getContextClassLoader());
+ cache.activateRegion(rootRegionName);
+
+ Node rootRegionNode = cache.get(rootRegionName);
+ Node fqnNode = cache.get(fqn);
+ assertNotNull(rootRegionNode);
+ assertNotNull(fqnNode);
+
+ assertEquals(fqnNode.get("another key"), "another value");
+ assertEquals(rootRegionNode.get("a key"), "a value");
+ }
+
+}
16 years, 6 months
JBoss Cache SVN: r6186 - in core/trunk/src/main/java/org/jboss/cache: commands/legacy/read and 6 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-07-07 10:39:36 -0400 (Mon, 07 Jul 2008)
New Revision: 6186
Modified:
core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java
core/trunk/src/main/java/org/jboss/cache/commands/legacy/read/PessGetChildrenNamesCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/legacy/write/PessRemoveNodeCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/read/GetChildrenNamesCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/read/GetNodeCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/EvictCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java
core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java
core/trunk/src/main/java/org/jboss/cache/invocation/AbstractInvocationContext.java
core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java
core/trunk/src/main/java/org/jboss/cache/mvcc/InternalNode.java
core/trunk/src/main/java/org/jboss/cache/mvcc/NodeReference.java
core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java
core/trunk/src/main/java/org/jboss/cache/mvcc/RepeatableReadNode.java
Log:
Improved various mvcc impl details
Modified: core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -523,6 +523,11 @@
return children;
}
+ public Map<Object, Node<K, V>> getChildrenMapDirect(boolean init)
+ {
+ return init ? children() : children;
+ }
+
public void setChildrenMapDirect(Map<Object, Node<K, V>> children)
{
if (children == null)
@@ -747,14 +752,8 @@
protected void copyInternals(UnversionedNode n)
{
- if (children == null || children.isEmpty())
- {
- n.children = null;
- }
- else
- {
- n.children().putAll(children);
- }
+ // direct reference to child map
+ n.children = children;
n.commandsFactory = commandsFactory;
n.delegate = delegate;
n.flags.clear();
Modified: core/trunk/src/main/java/org/jboss/cache/commands/legacy/read/PessGetChildrenNamesCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/legacy/read/PessGetChildrenNamesCommand.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/commands/legacy/read/PessGetChildrenNamesCommand.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -1,9 +1,14 @@
package org.jboss.cache.commands.legacy.read;
import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeSPI;
import org.jboss.cache.commands.read.GetChildrenNamesCommand;
import org.jboss.cache.invocation.InvocationContext;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
public class PessGetChildrenNamesCommand extends GetChildrenNamesCommand
{
public PessGetChildrenNamesCommand()
@@ -15,9 +20,18 @@
super(fqn);
}
- @Override
- public Object perform(InvocationContext ctx)
+ protected Set<Object> getCorrectedChildNames(Collection<NodeSPI> children, InvocationContext ctx)
{
- return fetchChildrenNames(ctx);
+ // prune deleted children - JBCACHE-1136
+ Set<Object> childNames = new HashSet<Object>();
+ for (NodeSPI child : children)
+ {
+ if (!child.isDeleted())
+ {
+ Object e = child.getFqn().getLastElement();
+ childNames.add(e);
+ }
+ }
+ return childNames;
}
}
Modified: core/trunk/src/main/java/org/jboss/cache/commands/legacy/write/PessRemoveNodeCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/legacy/write/PessRemoveNodeCommand.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/commands/legacy/write/PessRemoveNodeCommand.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -50,6 +50,11 @@
return found;
}
+ @Override
+ protected void recursivelyMarkAsRemoved(NodeSPI node, InvocationContext ctx)
+ {
+ node.markAsDeleted(true, true);
+ }
private void prepareForRollback(NodeSPI parentNode)
{
Modified: core/trunk/src/main/java/org/jboss/cache/commands/read/GetChildrenNamesCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/read/GetChildrenNamesCommand.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/commands/read/GetChildrenNamesCommand.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -9,6 +9,7 @@
import org.jboss.cache.mvcc.ReadCommittedNode;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -37,64 +38,58 @@
this.fqn = fqn;
}
- protected final Set<Object> fetchChildrenNames(InvocationContext ctx)
+ /**
+ * Retrieves the names of children for a specific Fqn.
+ *
+ * @param ctx invocation context
+ * @return a Set<Object> of child names, for a given Fqn, or null if the Fqn refers to a node that does not exist.
+ */
+ @SuppressWarnings("unchecked")
+ public Object perform(InvocationContext ctx)
{
NodeSPI n = fqn == null ? null : ctx.lookUpNode(fqn);
if (n == null || n.isDeleted()) return null;
Map childrenMap = n.getChildrenMapDirect();
- if (childrenMap == null || childrenMap.isEmpty()) return new HashSet<Object>();
- Set<Object> childNames = new HashSet<Object>();
- Collection s = childrenMap.values();
- // prune deleted children - JBCACHE-1136
- for (Object c : s)
- {
- NodeSPI child = (NodeSPI) c;
- if (!child.isDeleted())
- {
- Object e = child.getFqn().getLastElement();
- childNames.add(e);
- }
- }
- return childNames;
+ Collection<NodeSPI> children = (childrenMap == null || childrenMap.isEmpty()) ? Collections.emptySet() : childrenMap.values();
+
+ return getCorrectedChildNames(children, ctx);
}
-
/**
- * Retrieves the names of children for a specific Fqn.
+ * Cleans the collection of children passed in to extract child names into a Set. This implementation provides
+ * additional filtering such as removing known deleted children and adding known created ones.
*
- * @param ctx invocation context
- * @return a Set<Object> of child names, for a given Fqn, or null if the Fqn refers to a node that does not exist.
+ * @param children children set. Must not be null.
+ * @param ctx invocation context
+ * @return a set of valid children names.
*/
- public Object perform(InvocationContext ctx)
+ protected Set<Object> getCorrectedChildNames(Collection<NodeSPI> children, InvocationContext ctx)
{
- Set<Object> childNames = fetchChildrenNames(ctx);
+ Set<Object> childNames = new HashSet<Object>();
- if (trace) log.trace("Got child name set as " + childNames);
- // check for *new* children added.
- boolean modified = false;
+ for (NodeSPI realChild : children)
+ {
+ Fqn childFqn = realChild.getFqn();
+ NodeSPI childNode = ctx.lookUpNode(childFqn);
+
+ // deletion flag should be checked on what we get from the ctx.
+ // if childNode is null then it hasn't been removed in the current scope and hence should be included in this list.
+ if (childNode == null || !childNode.isDeleted()) childNames.add(childFqn.getLastElement());
+ }
+
+ // now check for any *new* children added.
for (Map.Entry<Fqn, NodeSPI> n : ctx.getLookedUpNodes().entrySet())
{
Fqn childFqn = n.getKey();
if (childFqn.getParent().equals(fqn))
{
- NodeSPI childNode = n.getValue();
- if (childNode.isDeleted())
- {
- childNames.remove(childFqn.getLastElement());
- modified = true;
- }
- else if (((ReadCommittedNode) childNode).isCreated())
- {
- childNames.add(childFqn.getLastElement());
- modified = true;
- }
+ ReadCommittedNode childNode = (ReadCommittedNode) n.getValue();
+ if (childNode.isCreated()) childNames.add(childFqn.getLastElement());
}
}
- if (trace && modified) log.trace("Modified child set to " + childNames);
return childNames;
}
-
public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable
{
return visitor.visitGetChildrenNamesCommand(ctx, this);
Modified: core/trunk/src/main/java/org/jboss/cache/commands/read/GetNodeCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/read/GetNodeCommand.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/commands/read/GetNodeCommand.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -1,5 +1,7 @@
package org.jboss.cache.commands.read;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.NodeSPI;
import org.jboss.cache.commands.Visitor;
@@ -17,6 +19,8 @@
public class GetNodeCommand extends AbstractDataCommand
{
public static final int METHOD_ID = 31;
+ private static final Log log = LogFactory.getLog(GetNodeCommand.class);
+ private static final boolean trace = log.isTraceEnabled();
public GetNodeCommand(Fqn fqn)
{
@@ -36,7 +40,13 @@
public Object perform(InvocationContext ctx)
{
NodeSPI node = ctx.lookUpNode(fqn);
- if (node != null && node.isDeleted()) return null;
+ if (node != null && node.isDeleted())
+ {
+ if (trace)
+ log.trace("Node of type [" + node.getClass().getSimpleName() + "] found but marked as deleted in current scope. Returning null.");
+ return null;
+ }
+ if (trace) log.trace("Found node, returning " + node);
return node;
}
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/EvictCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/EvictCommand.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/EvictCommand.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -126,7 +126,7 @@
parentNode.setChildrenLoaded(false);
}
node.setValid(false, false);
- node.markAsDeleted(true, false);
+ node.markAsDeleted(true);
return true;
}
}
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -9,6 +9,8 @@
import org.jboss.cache.optimistic.DataVersion;
import org.jboss.cache.transaction.GlobalTransaction;
+import java.util.Map;
+
/**
* Implements functionality defined by {@link org.jboss.cache.CacheSPI#removeNode(org.jboss.cache.Fqn)}
*
@@ -54,7 +56,7 @@
notifyBeforeRemove(targetNode, ctx);
boolean found = targetNode.isValid() && !targetNode.isDeleted();
- targetNode.markAsDeleted(true, true);
+ recursivelyMarkAsRemoved(targetNode, ctx);
// make sure we clear all data on this node!
targetNode.clearDataDirect();
@@ -63,6 +65,24 @@
return found;
}
+ /**
+ * Recursively marks a node as removed.
+ *
+ * @param node Node to mark
+ * @param ctx Invocation context
+ */
+ protected void recursivelyMarkAsRemoved(NodeSPI node, InvocationContext ctx)
+ {
+ node.markAsDeleted(true);
+ Fqn parentFqn = node.getFqn();
+ // recursion has to happen like this since child nodes are in the ctx.
+ Map<Fqn, NodeSPI> nodes = ctx.getLookedUpNodes();
+ for (Map.Entry<Fqn, NodeSPI> entry : nodes.entrySet())
+ {
+ if (entry.getKey().isChildOf(parentFqn)) entry.getValue().markAsDeleted(true);
+ }
+ }
+
private void notifyBeforeRemove(NodeSPI n, InvocationContext ctx)
{
if (!skipSendingNodeEvents)
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -360,7 +360,7 @@
protected void doAfterCall(InvocationContext ctx, VisitableCommand command)
{
// for non-transactional stuff.
- if (ctx.getTransaction() == null)
+ if (ctx.getTransactionContext() == null)
{
List<Fqn> locks;
if (!(locks = ctx.getLocks()).isEmpty())
@@ -381,12 +381,21 @@
}
ctx.clearLocks();
}
+ else
+ {
+ if (trace) log.trace("Nothing to do since there are no modifications in scope.");
+ }
}
+ else
+ {
+ if (trace)
+ log.trace("Nothing to do since there is a transaction in scope. Deferring writing changes. Ctx=" + ctx);
+ }
}
protected void transactionalCleanup(boolean commit, InvocationContext ctx)
{
- if (ctx.getTransaction() != null)
+ if (ctx.getTransactionContext() != null)
{
List<Fqn> locks;
if (!(locks = ctx.getTransactionContext().getLocks()).isEmpty())
@@ -418,6 +427,10 @@
ctx.clearLocks();
}
}
+ else
+ {
+ throw new IllegalStateException("Attempting to do a commit or rollback but there is no transactional context in scope. " + ctx);
+ }
}
// ----------------- actual implementation details ----------------------------
@@ -431,15 +444,21 @@
{
if (forceWriteLock)
{
+ if (trace) log.trace("Forcing lock on reading node " + f);
getWrappedNode(ctx, f, true, false, false);
}
else if (ctx.lookUpNode(f) == null)
{
+ if (trace) log.trace("Node " + f + " is not in context, fetching from container.");
// simple implementation. Peek the node, wrap it, put wrapped node in the context.
InternalNode node = dataContainer.peekInternalNode(f, false);
NodeSPI wrapped = nodeFactory.createMvccNode(node);
if (wrapped != null) ctx.putLookedUpNode(f, wrapped);
}
+ else
+ {
+ if (trace) log.trace("Node " + f + " is already in context.");
+ }
}
return invokeNextInterceptor(ctx, command);
}
Modified: core/trunk/src/main/java/org/jboss/cache/invocation/AbstractInvocationContext.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/AbstractInvocationContext.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/AbstractInvocationContext.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -198,6 +198,7 @@
return "InvocationContext{" +
"transaction=" + transaction +
", globalTransaction=" + globalTransaction +
+ ", transactionContext=" + transactionContext +
", optionOverrides=" + optionOverrides +
", originLocal=" + originLocal +
", txHasMods=" + txHasMods +
Modified: core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -290,12 +290,14 @@
if (child == null)
{
+ if (trace) log.trace("Child is null; creating.");
Option o2 = o1.copy();
spi.getInvocationContext().setOptionOverrides(o1);
spi.put(nf, null);
-
+ if (trace) log.trace("Created. Now getting again.");
spi.getInvocationContext().setOptionOverrides(o2);
child = getChild(f);
+ if (trace) log.trace("Got child " + child);
}
return child;
}
Modified: core/trunk/src/main/java/org/jboss/cache/mvcc/InternalNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/mvcc/InternalNode.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/InternalNode.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -109,6 +109,12 @@
boolean isResident();
+ /**
+ * Creates a new instance of the same type and copies internal state. Note that a shallow copy is made for all fields
+ * except the data map, where a new map is created.
+ *
+ * @return a copy.
+ */
InternalNode copy();
NodeLock getLock();
@@ -116,4 +122,12 @@
void addChild(Object nodeName, Node<K, V> nodeToAdd);
void printDetails(StringBuilder sb, int indent);
+
+ /**
+ * Very similar to getChildrenMapDirect() except that if the internal map is null, it initialises the map if init is true.
+ *
+ * @param init if true, will init internal data structures.
+ * @return a Map or null.
+ */
+ Map<Object, Node<K, V>> getChildrenMapDirect(boolean init);
}
Modified: core/trunk/src/main/java/org/jboss/cache/mvcc/NodeReference.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/mvcc/NodeReference.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/NodeReference.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -136,6 +136,11 @@
return delegate.getChildrenMapDirect();
}
+ public Map getChildrenMapDirect(boolean b)
+ {
+ return delegate.getChildrenMapDirect(b);
+ }
+
public void setChildrenMapDirect(Map children)
{
delegate.setChildrenMapDirect(children);
Modified: core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -10,10 +10,6 @@
import org.jboss.cache.optimistic.DataVersion;
import org.jboss.cache.optimistic.DefaultDataVersion;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
/**
* Repeatable read would do a simple delegation to the underlying node.
*
@@ -25,7 +21,8 @@
protected volatile InternalNode backup;
protected boolean changed;
protected boolean created;
- protected Set childrenAdded, childrenRemoved;
+ protected boolean deleted;
+// protected Set childrenAdded, childrenRemoved;
public ReadCommittedNode(InternalNode node)
{
@@ -51,51 +48,77 @@
{
if (changed)
{
- updateNode(container, nf, ctx);
+ Fqn fqn = getFqn();
+ if (trace)
+ log.trace("Updating node [" + fqn + "]. deleted=" + isDeleted() + " valid=" + isValid() + " changed" + isChanged() + " created=" + created);
+
+ // check if node has been deleted.
+ if (deleted)
+ {
+ if (!fqn.isRoot())
+ {
+ NodeSPI parent = lookupParent(fqn, ctx, container);
+ parent.removeChildDirect(fqn.getLastElement());
+ }
+ else
+ {
+ log.warn("Attempting to remove the root node. Not doing anything!");
+ }
+ }
+ else if (created)
+ {
+ // add newly created nodes to parents.
+ NodeSPI parent = lookupParent(fqn, ctx, container);
+ parent.addChildDirect(nf.createNodeInvocationDelegate(node));
+ }
+ else if (fqn.isRoot())
+ {
+ // set root node reference in data container.
+ container.setRoot(nf.createNodeInvocationDelegate(node));
+ }
+ else
+ {
+ updateNode(container, nf, ctx);
+ }
+
changed = false;
backup = null;
}
}
- protected NodeSPI lookupParent(Fqn fqn, InvocationContext ctx, DataContainer container)
+ /**
+ * Performs a lookup for the parent node of the Fqn passed in. The context is checked first, and failing that, the
+ * data container is consulted.
+ *
+ * @param fqn Fqn whos parent to locate
+ * @param ctx invocation context
+ * @param container data container
+ * @return Parent node, never null.
+ * @throws NodeNotExistsException if the parent node cannot be found in any scope or data container.
+ */
+ protected final NodeSPI lookupParent(Fqn fqn, InvocationContext ctx, DataContainer container) throws NodeNotExistsException
{
Fqn parentFqn = fqn.getParent();
NodeSPI parent = ctx.lookUpNode(parentFqn);
if (parent != null) return parent;
parent = container.peek(parentFqn);
+ if (parent == null)
+ throw new NodeNotExistsException("Node " + parentFqn + " cannot be found in any context or data container!");
return parent;
}
- protected void updateNode(DataContainer container, NodeFactory nf, InvocationContext ctx)
+ /**
+ * Updates state changes on the current node in the underlying data structure.
+ *
+ * @param dataContainer data container
+ * @param nf node factory
+ * @param ctx invocation context
+ */
+ protected void updateNode(DataContainer dataContainer, NodeFactory nf, InvocationContext ctx)
{
- Fqn fqn = getFqn();
- if (trace)
- log.trace("Updating node [" + fqn + "]. deleted=" + isDeleted() + " valid=" + isValid() + " changed" + isChanged() + " created=" + created);
- if (isDeleted())
- {
- if (!fqn.isRoot())
- {
- NodeSPI parent = lookupParent(fqn, ctx, container);
- parent.removeChildDirect(fqn.getLastElement());
- }
- else
- {
- log.warn("Attempting to remove the root node. Not doing anything!");
- }
- }
- else if (created)
- {
- NodeSPI parent = lookupParent(fqn, ctx, container);
- if (parent == null)
- throw new NodeNotExistsException("Cannot add node " + fqn + " to data structure since its parent is null!");
- parent.addChildDirect(nf.createNodeInvocationDelegate(node));
- }
- else
- {
- mergeChildren(backup.getChildrenMapDirect());
- ((NodeReference) backup).setDelegate(((NodeReference) node).getDelegate());
- node = backup;
- }
+ // swap refs
+ ((NodeReference) backup).setDelegate(((NodeReference) node).getDelegate());
+ node = backup;
}
public void rollbackUpdate()
@@ -135,42 +158,23 @@
return backup;
}
+ // do not propagate deletion flags to the underlying node.
+
@Override
- public void addChildDirect(NodeSPI child)
+ public boolean isDeleted()
{
- Object childname = child.getFqn().getLastElement();
- if (childrenAdded == null) childrenAdded = new HashSet();
- childrenAdded.add(childname);
- if (childrenRemoved != null) childrenRemoved.remove(childname);
- super.addChildDirect(child);
+ return deleted;
}
@Override
- public boolean removeChildDirect(Object childname)
+ public void markAsDeleted(boolean deleted)
{
- boolean rv = super.removeChildDirect(childname);
- if (rv)
- {
- if (childrenRemoved == null) childrenRemoved = new HashSet();
- childrenRemoved.add(childname);
- if (childrenAdded != null) childrenAdded.remove(childname);
- }
- return rv;
+ this.deleted = deleted;
}
- protected void mergeChildren(Map oldChildren)
+ @Override
+ public void markAsDeleted(boolean deleted, boolean recursive)
{
- if (oldChildren == null || oldChildren.isEmpty()) return; // nothing to do.
- Map childmap = node.getChildrenMapDirect();
- node.setChildrenMapDirect(oldChildren);
- if (childrenRemoved != null)
- {
- for (Object name : childrenRemoved) node.removeChildDirect(name);
- }
-
- if (childrenAdded != null)
- {
- for (Object name : childrenAdded) node.addChildDirect((NodeSPI) childmap.get(name));
- }
+ throw new UnsupportedOperationException("Recursive deletion not allowed!");
}
}
Modified: core/trunk/src/main/java/org/jboss/cache/mvcc/RepeatableReadNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/mvcc/RepeatableReadNode.java 2008-07-07 14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/RepeatableReadNode.java 2008-07-07 14:39:36 UTC (rev 6186)
@@ -3,7 +3,6 @@
import org.jboss.cache.DataContainer;
import org.jboss.cache.Fqn;
import org.jboss.cache.NodeFactory;
-import org.jboss.cache.NodeNotExistsException;
import org.jboss.cache.NodeSPI;
import org.jboss.cache.invocation.InvocationContext;
import org.jboss.cache.optimistic.DataVersion;
@@ -54,41 +53,7 @@
@Override
protected void updateNode(DataContainer dataContainer, NodeFactory nf, InvocationContext ctx)
{
- Fqn fqn = getFqn();
- if (trace)
- log.trace("Updating node [" + fqn + "]. deleted=" + isDeleted() + " valid=" + isValid() + " changed" + isChanged() + " created=" + created);
-
- if (fqn.isRoot())
- {
- dataContainer.setRoot(nf.createNodeInvocationDelegate(node));
- }
- else if (created)
- {
- NodeSPI parent = lookupParent(fqn, ctx, dataContainer);
- if (parent == null)
- throw new NodeNotExistsException("Cannot add node " + fqn + " to data structure since its parent is null!");
- parent.addChildDirect(nf.createNodeInvocationDelegate(node));
- }
- else
- {
- NodeSPI parent = lookupParent(fqn, ctx, dataContainer);
- if (parent != null)
- {
- Object name = fqn.getLastElement();
- NodeSPI oldChild = parent.getChildDirect(name);
- if (isDeleted())
- {
- parent.removeChildDirect(name);
- }
- else
- {
- if (oldChild != null)
- {
- mergeChildren(oldChild.getChildrenMapDirect());
- }
- parent.addChildDirect(nf.createNodeInvocationDelegate(node));
- }
- }
- }
+ NodeSPI parent = lookupParent(getFqn(), ctx, dataContainer);
+ parent.addChildDirect(nf.createNodeInvocationDelegate(node));
}
}
16 years, 6 months
JBoss Cache SVN: r6185 - core/trunk/src/main/java/org/jboss/cache.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-07-07 10:38:55 -0400 (Mon, 07 Jul 2008)
New Revision: 6185
Modified:
core/trunk/src/main/java/org/jboss/cache/DataContainerImpl.java
Log:
root node ref should be volatile
Modified: core/trunk/src/main/java/org/jboss/cache/DataContainerImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/DataContainerImpl.java 2008-07-07 14:38:23 UTC (rev 6184)
+++ core/trunk/src/main/java/org/jboss/cache/DataContainerImpl.java 2008-07-07 14:38:55 UTC (rev 6185)
@@ -34,7 +34,7 @@
/**
* Root node.
*/
- private NodeSPI root;
+ private volatile NodeSPI root;
/**
* Set<Fqn> of Fqns of the topmost node of internal regions that should
16 years, 6 months