[jbosscache-commits] JBoss Cache SVN: r6182 - in core/trunk/src: main/java/org/jboss/cache/interceptors and 4 other directories.
jbosscache-commits at lists.jboss.org
jbosscache-commits at lists.jboss.org
Fri Jul 4 09:44:11 EDT 2008
Author: manik.surtani at jboss.com
Date: 2008-07-04 09:44:11 -0400 (Fri, 04 Jul 2008)
New Revision: 6182
Modified:
core/trunk/src/main/java/org/jboss/cache/commands/read/GetChildrenNamesCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/read/GetKeyValueCommand.java
core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java
core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java
core/trunk/src/main/java/org/jboss/cache/mvcc/RepeatableReadNode.java
core/trunk/src/test/java/org/jboss/cache/api/mvcc/LockTestBase.java
core/trunk/src/test/java/org/jboss/cache/api/mvcc/read_committed/ReadCommittedLockParentTest.java
core/trunk/src/test/java/org/jboss/cache/api/mvcc/repeatable_read/RepeatableReadLockParentTest.java
Log:
pre-optimised, but correct. Very ugly with unnecessary casts and loops.
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-04 12:13:44 UTC (rev 6181)
+++ core/trunk/src/main/java/org/jboss/cache/commands/read/GetChildrenNamesCommand.java 2008-07-04 13:44:11 UTC (rev 6182)
@@ -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;
@@ -23,6 +25,8 @@
public class GetChildrenNamesCommand extends AbstractDataCommand
{
public static final int METHOD_ID = 23;
+ private static final Log log = LogFactory.getLog(GetChildrenNamesCommand.class);
+ private static final boolean trace = log.isTraceEnabled();
public GetChildrenNamesCommand()
{
@@ -65,22 +69,28 @@
{
Set<Object> childNames = fetchChildrenNames(ctx);
+ if (trace) log.trace("Got child name set as " + childNames);
// check for *new* children added.
+ boolean modified = false;
for (Map.Entry<Fqn, NodeSPI> n : ctx.getLookedUpNodes().entrySet())
{
- if (n.getKey().getParent().equals(fqn))
+ Fqn childFqn = n.getKey();
+ if (childFqn.getParent().equals(fqn))
{
- if (n.getValue().isDeleted())
+ NodeSPI childNode = n.getValue();
+ if (childNode.isDeleted())
{
- childNames.remove(n.getKey());
+ childNames.remove(childFqn.getLastElement());
+ modified = true;
}
- else if (((ReadCommittedNode) n.getValue()).isCreated())
+ else if (((ReadCommittedNode) childNode).isCreated())
{
- childNames.add(n.getKey().getLastElement());
+ childNames.add(childFqn.getLastElement());
+ modified = true;
}
}
}
-
+ if (trace && modified) log.trace("Modified child set to " + childNames);
return childNames;
}
Modified: core/trunk/src/main/java/org/jboss/cache/commands/read/GetKeyValueCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/read/GetKeyValueCommand.java 2008-07-04 12:13:44 UTC (rev 6181)
+++ core/trunk/src/main/java/org/jboss/cache/commands/read/GetKeyValueCommand.java 2008-07-04 13:44:11 UTC (rev 6182)
@@ -52,11 +52,6 @@
*/
public Object perform(InvocationContext ctx)
{
- if (trace)
- {
- log.trace(new StringBuilder("get(").append("\"").append(fqn).append("\", \"").append(key).append("\", \"").
- append(sendNodeEvent).append("\")"));
- }
NodeSPI n = ctx.lookUpNode(fqn);
if (n == null)
{
@@ -65,11 +60,12 @@
}
if (n.isDeleted())
{
- if (trace) log.trace("Node has been deleted!");
+ if (trace) log.trace("Node has been deleted and is of type " + n.getClass().getSimpleName());
return null;
}
if (sendNodeEvent) notifier.notifyNodeVisited(fqn, true, ctx);
Object result = n.getDirect(key);
+ if (trace) log.trace("Found value " + result);
if (sendNodeEvent) notifier.notifyNodeVisited(fqn, false, ctx);
return result;
}
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 12:13:44 UTC (rev 6181)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java 2008-07-04 13:44:11 UTC (rev 6182)
@@ -88,7 +88,9 @@
protected boolean doBeforeCall(InvocationContext ctx, VisitableCommand command)
{
if (ctx.getOptionOverrides().isSuppressLocking())
- throw new CacheException("Lock suppression not supported with MVCC!");
+ {
+ if (log.isWarnEnabled()) log.warn("Lock suppression not supported with MVCC!");
+ }
return true;
}
@@ -366,7 +368,6 @@
// clean up.
Fqn[] fqnsToUnlock = new Fqn[locks.size()];
fqnsToUnlock = locks.toArray(fqnsToUnlock);
- if (trace) log.trace("Releasing locks for thread " + Thread.currentThread() + " on fqns " + locks);
Object owner = Thread.currentThread();
for (int i = fqnsToUnlock.length - 1; i > -1; i--)
@@ -375,6 +376,7 @@
ReadCommittedNode rcn = (ReadCommittedNode) ctx.lookUpNode(fqnsToUnlock[i]);
if (rcn != null) rcn.commitUpdate(dataContainer, nodeFactory, ctx); // could be null with read-committed
// and then unlock
+ if (trace) log.trace("Releasing lock on [" + fqnsToUnlock[i] + "] for thread " + owner);
lockManager.unlock(fqnsToUnlock[i], owner);
}
ctx.clearLocks();
@@ -386,7 +388,6 @@
{
if (ctx.getTransaction() != null)
{
- if (trace) log.trace("Releasing locks for transaction " + ctx.getGlobalTransaction());
List<Fqn> locks;
if (!(locks = ctx.getTransactionContext().getLocks()).isEmpty())
{
@@ -411,6 +412,7 @@
}
}
// and then unlock
+ if (trace) log.trace("Releasing lock on [" + fqnsToUnlock[i] + "] for transaction " + owner);
lockManager.unlock(fqnsToUnlock[i], owner);
}
ctx.clearLocks();
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-04 12:13:44 UTC (rev 6181)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java 2008-07-04 13:44:11 UTC (rev 6182)
@@ -10,6 +10,10 @@
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.
*
@@ -21,6 +25,7 @@
protected volatile InternalNode backup;
protected boolean changed;
protected boolean created;
+ protected Set childrenAdded, childrenRemoved;
public ReadCommittedNode(InternalNode node)
{
@@ -63,9 +68,11 @@
protected void updateNode(DataContainer container, NodeFactory nf, InvocationContext ctx)
{
+ Fqn fqn = getFqn();
+ if (trace)
+ log.trace("Updating node [" + fqn + "]. deleted=" + isDeleted() + " valid=" + isValid() + " changed" + isChanged() + " created=" + created);
if (isDeleted())
{
- Fqn fqn = getFqn();
if (!fqn.isRoot())
{
NodeSPI parent = lookupParent(fqn, ctx, container);
@@ -78,7 +85,6 @@
}
else if (created)
{
- Fqn fqn = getFqn();
NodeSPI parent = lookupParent(fqn, ctx, container);
if (parent == null)
throw new NodeNotExistsException("Cannot add node " + fqn + " to data structure since its parent is null!");
@@ -86,6 +92,7 @@
}
else
{
+ mergeChildren(backup.getChildrenMapDirect());
((NodeReference) backup).setDelegate(((NodeReference) node).getDelegate());
node = backup;
}
@@ -127,4 +134,43 @@
{
return backup;
}
+
+ @Override
+ public void addChildDirect(NodeSPI child)
+ {
+ Object childname = child.getFqn().getLastElement();
+ if (childrenAdded == null) childrenAdded = new HashSet();
+ childrenAdded.add(childname);
+ if (childrenRemoved != null) childrenRemoved.remove(childname);
+ super.addChildDirect(child);
+ }
+
+ @Override
+ public boolean removeChildDirect(Object childname)
+ {
+ boolean rv = super.removeChildDirect(childname);
+ if (rv)
+ {
+ if (childrenRemoved == null) childrenRemoved = new HashSet();
+ childrenRemoved.add(childname);
+ if (childrenAdded != null) childrenAdded.remove(childname);
+ }
+ return rv;
+ }
+
+ protected void mergeChildren(Map oldChildren)
+ {
+ 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));
+ }
+ }
}
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-04 12:13:44 UTC (rev 6181)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/RepeatableReadNode.java 2008-07-04 13:44:11 UTC (rev 6182)
@@ -54,10 +54,10 @@
@Override
protected void updateNode(DataContainer dataContainer, NodeFactory nf, InvocationContext ctx)
{
+ Fqn fqn = getFqn();
if (trace)
- log.trace("Updating RepeatableReadNode. IsDeleted? " + isDeleted() + " isValid? " + isValid() + " isChanged? " + isChanged());
+ log.trace("Updating node [" + fqn + "]. deleted=" + isDeleted() + " valid=" + isValid() + " changed" + isChanged() + " created=" + created);
- Fqn fqn = getFqn();
if (fqn.isRoot())
{
dataContainer.setRoot(nf.createNodeInvocationDelegate(node));
@@ -75,17 +75,17 @@
if (parent != null)
{
Object name = fqn.getLastElement();
-// NodeSPI oldChild = parent.getChildDirect(name);
+ NodeSPI oldChild = parent.getChildDirect(name);
if (isDeleted())
{
parent.removeChildDirect(name);
}
else
{
-// if (oldChild != null)
-// {
-// node.setChildrenMapDirect(oldChild.getChildrenMapDirect());
-// }
+ if (oldChild != null)
+ {
+ mergeChildren(oldChild.getChildrenMapDirect());
+ }
parent.addChildDirect(nf.createNodeInvocationDelegate(node));
}
}
Modified: core/trunk/src/test/java/org/jboss/cache/api/mvcc/LockTestBase.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/mvcc/LockTestBase.java 2008-07-04 12:13:44 UTC (rev 6181)
+++ core/trunk/src/test/java/org/jboss/cache/api/mvcc/LockTestBase.java 2008-07-04 13:44:11 UTC (rev 6182)
@@ -540,4 +540,33 @@
assert cache.getNode(A).hasChild(AB.getLastElement()) == false;
assert cache.getNode(AB) == null;
}
+
+ public void testOverwritingOnInsert() throws Exception
+ {
+ cache.put(AB, "k", "v");
+
+ tm.begin();
+ cache.put(ABC, "k", "v");
+ assert "v".equals(cache.get(ABC, "k"));
+ assert "v".equals(cache.get(AB, "k"));
+ Transaction t1 = tm.suspend();
+
+ tm.begin();
+ cache.put(AB, "k", "v2");
+ assert "v2".equals(cache.get(AB, "k"));
+ assert null == cache.get(ABC, "k");
+ Transaction t2 = tm.suspend();
+
+ tm.resume(t1);
+ t1.commit();
+
+ assert "v".equals(cache.get(AB, "k"));
+ assert "v".equals(cache.get(ABC, "k"));
+
+ tm.resume(t2);
+ t2.commit();
+
+ assert "v2".equals(cache.get(AB, "k"));
+ assert "v".equals(cache.get(ABC, "k"));
+ }
}
Modified: core/trunk/src/test/java/org/jboss/cache/api/mvcc/read_committed/ReadCommittedLockParentTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/mvcc/read_committed/ReadCommittedLockParentTest.java 2008-07-04 12:13:44 UTC (rev 6181)
+++ core/trunk/src/test/java/org/jboss/cache/api/mvcc/read_committed/ReadCommittedLockParentTest.java 2008-07-04 13:44:11 UTC (rev 6182)
@@ -9,4 +9,10 @@
{
lockParentForChildInsertRemove = true;
}
+
+ @Override
+ public void testOverwritingOnInsert()
+ {
+ // no op since a locked parent makes tis test irrelevant.
+ }
}
Modified: core/trunk/src/test/java/org/jboss/cache/api/mvcc/repeatable_read/RepeatableReadLockParentTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/mvcc/repeatable_read/RepeatableReadLockParentTest.java 2008-07-04 12:13:44 UTC (rev 6181)
+++ core/trunk/src/test/java/org/jboss/cache/api/mvcc/repeatable_read/RepeatableReadLockParentTest.java 2008-07-04 13:44:11 UTC (rev 6182)
@@ -9,4 +9,10 @@
{
lockParentForChildInsertRemove = true;
}
+
+ @Override
+ public void testOverwritingOnInsert()
+ {
+ // no op since a locked parent makes tis test irrelevant.
+ }
}
More information about the jbosscache-commits
mailing list