Author: manik.surtani(a)jboss.com
Date: 2008-07-04 04:53:09 -0400 (Fri, 04 Jul 2008)
New Revision: 6171
Added:
core/trunk/src/test/java/org/jboss/cache/api/mvcc/ForceWriteLockTest.java
Modified:
core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java
core/trunk/src/test/java/org/jboss/cache/api/mvcc/repeatable_read/NodeMoveMvccTest.java
core/trunk/src/test/java/org/jboss/cache/options/ForceWriteLockTest.java
Log:
Preliminary move() + forceWriteLock logic
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-04
08:52:44 UTC (rev 6170)
+++
core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java 2008-07-04
08:53:09 UTC (rev 6171)
@@ -37,7 +37,6 @@
import org.jboss.cache.mvcc.NullMarkerNode;
import org.jboss.cache.mvcc.ReadCommittedNode;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@@ -52,14 +51,6 @@
*/
public class MVCCLockingInterceptor extends PostProcessingCommandInterceptor
{
- // TODO: Implement me.
-
- // Need to think about how this will behave with 1. LockParentForChildInsertRemove
and 2. CacheLoading.
-
- // Need to think further about cached node lookups. Walking the tree sucks ass.
-
- // How will wrapper nodes unwrap?
-
boolean allowWriteSkew;
LockManager lockManager;
DataContainer dataContainer;
@@ -227,8 +218,11 @@
@Override
public Object handleInvalidateCommand(InvocationContext ctx, InvalidateCommand
command) throws Throwable
{
- // TODO : Handle this properly
- return handleWriteCommand(ctx, command, new ArrayList<Fqn>(1),
Collections.singletonList(command.getFqn()));
+ // this should be handled the same as a recursive evict command.
+ ctx.getOptionOverrides().setLockAcquisitionTimeout(0);
+ addNodeAndParentForRemoval(ctx, command.getFqn(), true);
+
+ return invokeNextInterceptor(ctx, command);
}
@Override
@@ -277,11 +271,22 @@
@Override
public Object handleMoveCommand(InvocationContext ctx, MoveCommand command) throws
Throwable
{
- // TODO : Handle this properly
- List<Fqn> list = new ArrayList<Fqn>();
- list.add(command.getFqn());
- list.add(command.getTo());
- return handleWriteCommand(ctx, command, new ArrayList<Fqn>(1), list);
+ // 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);
+
+ // now lock the new parent.
+ getWrappedNode(ctx, command.getTo(), 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)
+ {
+ getWrappedNode(ctx, Fqn.fromRelativeFqn(command.getTo(), f), true, true, true);
+ }
+
+ // now pass up the chain.
+ return invokeNextInterceptor(ctx, command);
}
@Override
@@ -394,11 +399,17 @@
protected Object handleReadCommand(InvocationContext ctx, VisitableCommand command,
List<Fqn> fqns) throws Throwable
{
+ boolean forceWriteLock = ctx.getOptionOverrides().isForceWriteLock();
+
// does the node exist in the context?
for (Fqn f : fqns)
{
- if (ctx.lookUpNode(f) == null)
+ if (forceWriteLock)
{
+ getWrappedNode(ctx, f, true, false, false);
+ }
+ else if (ctx.lookUpNode(f) == null)
+ {
// simple implementation. Peek the node, wrap it, put wrapped node in the
context.
InternalNode node = dataContainer.peekInternalNode(f, false);
NodeSPI wrapped = nodeFactory.createMvccNode(node);
@@ -408,41 +419,6 @@
return invokeNextInterceptor(ctx, command);
}
- // TODO : this method is probably unnecessary
- protected Object handleWriteCommand(InvocationContext ctx, VisitableCommand command,
List<Fqn> fqnsToRead, List<Fqn> fqnsToWrite) throws Throwable
- {
- for (Fqn f : fqnsToRead)
- {
- if (ctx.lookUpNode(f) == null)
- {
- // simple implementation. Peek the node, wrap it, put wrapped node in the
context.
- InternalNode node = dataContainer.peekInternalNode(f, false);
- if (node != null)
- {
- NodeSPI wrapped = nodeFactory.createMvccNode(node);
- ctx.putLookedUpNode(f, wrapped);
- }
- }
- }
-
- for (Fqn f : fqnsToWrite)
- {
- if (ctx.lookUpNode(f) == null)
- {
- // simple implementation. Peek the node, wrap it, put wrapped node in the
context.
- InternalNode node = dataContainer.peekInternalNode(f, false);
- if (node != null)
- {
- lock(ctx, f);
- NodeSPI wrapped = nodeFactory.createMvccNode(node);
- ctx.putLookedUpNode(f, wrapped);
- }
- }
- }
-
- return invokeNextInterceptor(ctx, command);
- }
-
/**
* First checks in contexts for the existence of the node. If it does exist, it will
return it, acquiring a lock if
* necessary. Otherwise, it will peek in the dataContainer, wrap the node, lock if
necessary, and add it to the context.
Added: core/trunk/src/test/java/org/jboss/cache/api/mvcc/ForceWriteLockTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/mvcc/ForceWriteLockTest.java
(rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/api/mvcc/ForceWriteLockTest.java 2008-07-04
08:53:09 UTC (rev 6171)
@@ -0,0 +1,38 @@
+package org.jboss.cache.api.mvcc;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.jboss.cache.lock.LockManager;
+import org.jboss.cache.lock.LockType;
+import org.jboss.cache.util.TestingUtil;
+import static org.testng.AssertJUnit.assertTrue;
+import org.testng.annotations.Test;
+
+@Test(groups = {"functional", "mvcc"})
+public class ForceWriteLockTest extends org.jboss.cache.options.ForceWriteLockTest
+{
+ public ForceWriteLockTest()
+ {
+ nodeLockingScheme = NodeLockingScheme.MVCC;
+ }
+
+ @Override
+ protected void assertNotLocked(Fqn fqn)
+ {
+ assert !TestingUtil.extractLockManager(cache).isLocked(cache.peek(fqn, true)) :
"Node " + fqn + " is locked!!";
+ }
+
+ @Override
+ protected void assertLocked(Object owner, Fqn fqn, boolean write_locked)
+ {
+ if (write_locked)
+ {
+ LockManager lm = TestingUtil.extractLockManager(cache);
+ NodeSPI<String, String> n = cache.peek(fqn, true);
+ if (owner == null) owner = Thread.currentThread();
+ assertTrue("node " + fqn + " is not locked",
lm.isLocked(n));
+ assertTrue("node " + fqn + " is not write-locked by owner "
+ owner, lm.ownsLock(fqn, LockType.WRITE, owner));
+ }
+ }
+}
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-04
08:52:44 UTC (rev 6170)
+++
core/trunk/src/test/java/org/jboss/cache/api/mvcc/repeatable_read/NodeMoveMvccTest.java 2008-07-04
08:53:09 UTC (rev 6171)
@@ -43,7 +43,7 @@
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);
+ LockAssert.assertLocked(Fqn.fromRelativeFqn(Fqn.fromRelativeFqn(A, B), C), lm,
icc);
}
@Override
Modified: core/trunk/src/test/java/org/jboss/cache/options/ForceWriteLockTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/options/ForceWriteLockTest.java 2008-07-04
08:52:44 UTC (rev 6170)
+++ core/trunk/src/test/java/org/jboss/cache/options/ForceWriteLockTest.java 2008-07-04
08:53:09 UTC (rev 6171)
@@ -27,16 +27,17 @@
@Test(groups = {"functional", "pessimistic"})
public class ForceWriteLockTest
{
- private CacheSPI<String, String> cache;
+ protected CacheSPI<String, String> cache;
private Fqn fqn = Fqn.fromString("/a/b");
private TransactionManager tm;
+ protected NodeLockingScheme nodeLockingScheme = NodeLockingScheme.PESSIMISTIC;
@BeforeMethod(alwaysRun = true)
public void setUp()
{
Configuration c = new Configuration();
c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
- c.setNodeLockingScheme(NodeLockingScheme.PESSIMISTIC);
+ c.setNodeLockingScheme(nodeLockingScheme);
CacheFactory<String, String> instance = new DefaultCacheFactory<String,
String>();
cache = (CacheSPI<String, String>) instance.createCache(c);
tm = cache.getTransactionManager();
@@ -45,15 +46,7 @@
@AfterMethod(alwaysRun = true)
public void tearDown()
{
- try
- {
- tm.rollback();
- }
- catch (Exception e)
- {
- // ignore
- }
- cache.stop();
+ TestingUtil.killCaches(cache);
}
public void testControl() throws Exception
@@ -116,12 +109,12 @@
testControl();
}
- private void assertNotLocked(Fqn fqn)
+ protected void assertNotLocked(Fqn fqn)
{
assert !TestingUtil.extractLockManager(cache).isLocked(cache.peek(fqn, true)) :
"Node " + fqn + " is locked!!";
}
- private void assertLocked(Object owner, Fqn fqn, boolean write_locked)
+ protected void assertLocked(Object owner, Fqn fqn, boolean write_locked)
{
LockManager lm = TestingUtil.extractLockManager(cache);
NodeSPI<String, String> n = cache.peek(fqn, true);
@@ -136,5 +129,4 @@
assertTrue("node " + fqn + " is not read-locked by owner " +
owner, lm.ownsLock(fqn, LockType.READ, owner));
}
}
-
}