JBoss Cache SVN: r7919 - enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE.
by jbosscache-commits@lists.jboss.org
Author: jdimanos(a)jboss.com
Date: 2009-03-19 04:35:15 -0400 (Thu, 19 Mar 2009)
New Revision: 7919
Modified:
enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Colophon.po
Log:
update
Modified: enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Colophon.po
===================================================================
--- enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Colophon.po 2009-03-19 07:33:01 UTC (rev 7918)
+++ enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Colophon.po 2009-03-19 08:35:15 UTC (rev 7919)
@@ -1,26 +1,28 @@
+# translation of Colophon.po to
msgid ""
msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
+"Project-Id-Version: Colophon\n"
"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
"POT-Creation-Date: 2008-09-21 04:57+0000\n"
-"PO-Revision-Date: 2007-04-17 00:25-0500\n"
-"Last-Translator: Automatically generated\n"
-"Language-Team: none\n"
+"PO-Revision-Date: 2009-03-19 19:29+1100\n"
+"Last-Translator: \n"
+"Language-Team: <en(a)li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
#. Tag: title
#: Colophon.xml:4
#, no-c-format
msgid "Bibliography"
-msgstr ""
+msgstr "Bibliografie"
#. Tag: title
#: Colophon.xml:5
#, no-c-format
msgid "Authors"
-msgstr ""
+msgstr "Autoren"
#. Tag: author
#: Colophon.xml:6
@@ -29,6 +31,8 @@
"<honorific>Mr</honorific><firstname>Norman</firstname> <surname>Walsh</"
"surname>"
msgstr ""
+"<honorific>Mr</honorific><firstname>Norman</firstname> <surname>Walsh</"
+"surname>"
#. Tag: affiliation
#: Colophon.xml:9
@@ -38,21 +42,25 @@
"jobtitle><orgname>ArborText, Inc.</orgname><orgdiv>Application Developement</"
"orgdiv>"
msgstr ""
+"<shortaffil>ATI</shortaffil><jobtitle>Senior Application Analyst</"
+"jobtitle><orgname>ArborText, Inc.</orgname><orgdiv>Application Developement</"
+"orgdiv>"
#. Tag: title
#: Colophon.xml:11
#, no-c-format
msgid "Translator"
-msgstr ""
+msgstr "Übersetzer"
#. Tag: othercredit
#: Colophon.xml:12
#, no-c-format
msgid "<firstname>John</firstname> <surname>Doe</surname>"
-msgstr ""
+msgstr "<firstname>Jasna</firstname> <surname>Dimanoski</surname>"
#. Tag: contrib
#: Colophon.xml:14
#, no-c-format
msgid "Extensive review and rough drafts of Section 1.3, 1.4, and 1.5"
msgstr ""
+
15 years, 9 months
JBoss Cache SVN: r7918 - enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE.
by jbosscache-commits@lists.jboss.org
Author: jdimanos(a)jboss.com
Date: 2009-03-19 03:33:01 -0400 (Thu, 19 Mar 2009)
New Revision: 7918
Modified:
enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Book_Info.po
Log:
update
Modified: enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Book_Info.po
===================================================================
--- enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Book_Info.po 2009-03-19 07:30:49 UTC (rev 7917)
+++ enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Book_Info.po 2009-03-19 07:33:01 UTC (rev 7918)
@@ -1,39 +1,42 @@
+# translation of Book_Info.po to
# Language /tmp/mike/JBEAP420/Cache translations for JBEAP package.
-# Copyright (C) 2007 Free Software Foundation, Inc.
+# Copyright (C) 2007, 2009 Free Software Foundation, Inc.
# Automatically generated, 2007.
#
msgid ""
msgstr ""
-"Project-Id-Version: JBEAP 420\n"
+"Project-Id-Version: Book_Info\n"
"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
"POT-Creation-Date: 2008-09-21 04:57+0000\n"
-"PO-Revision-Date: 2001-02-09 01:25+0100\n"
-"Last-Translator: Automatically generated\n"
-"Language-Team: none\n"
+"PO-Revision-Date: 2009-03-19 18:32+1100\n"
+"Last-Translator: \n"
+"Language-Team: <en(a)li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
#. Tag: title
#: Book_Info.xml:5
#, no-c-format
msgid "JBoss Cache Pojo Cache Guide"
-msgstr ""
+msgstr "JBoss Cache Pojo Cache Handbuch"
#. Tag: subtitle
#: Book_Info.xml:6
#, no-c-format
msgid "for Use with JBoss Enterprise Application Platform 4.3"
-msgstr ""
+msgstr "zur Verwendung mit JBoss Enterprise Application Platform 4.3"
#. Tag: para
#: Book_Info.xml:12
#, no-c-format
msgid "This book is a User Guide for Pojo Cache"
-msgstr ""
+msgstr "Dieses Buch ist ein Benutzerhandbuch für Pojo Cache"
#. Tag: holder
#: Book_Info.xml:26
#, no-c-format
msgid "&HOLDER;"
-msgstr ""
+msgstr "&HOLDER;"
+
15 years, 9 months
JBoss Cache SVN: r7917 - enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE.
by jbosscache-commits@lists.jboss.org
Author: jdimanos(a)jboss.com
Date: 2009-03-19 03:30:49 -0400 (Thu, 19 Mar 2009)
New Revision: 7917
Modified:
enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Api.po
Log:
update
Modified: enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Api.po
===================================================================
--- enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Api.po 2009-03-19 07:30:26 UTC (rev 7916)
+++ enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Api.po 2009-03-19 07:30:49 UTC (rev 7917)
@@ -8,7 +8,7 @@
"Project-Id-Version: Api\n"
"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
"POT-Creation-Date: 2008-09-21 04:57+0000\n"
-"PO-Revision-Date: 2009-03-19 18:29+1100\n"
+"PO-Revision-Date: 2009-03-19 18:30+1100\n"
"Last-Translator: \n"
"Language-Team: <en(a)li.org>\n"
"MIME-Version: 1.0\n"
@@ -53,6 +53,13 @@
"*/\n"
"Object putObject(Fqn fqn, Object pojo) throws CacheException;"
msgstr ""
+"/*\n"
+" * @param fqn The fqn instance to associate with the object in the cache.\n"
+" * @param pojo aop-enabled object to be inserted into the cache. If null,\n"
+" * it will nullify the fqn node.\n"
+" * @throws CacheException\n"
+"*/\n"
+"Object putObject(Fqn fqn, Object pojo) throws CacheException;"
#. Tag: para
#: Api.xml:11
@@ -133,6 +140,16 @@
" */\n"
"Object removeObject(Fqn fqn) throws CacheException;"
msgstr ""
+"/**\n"
+" * Remove aop-enabled object from the cache. After successful call of this "
+"API, the returning\n"
+" * POJO is no longer managed by the cache.\n"
+" *\n"
+" * @param fqn Instance that associates with this node.\n"
+" * @return Original POJO stored under this node.\n"
+" * @throws CacheException\n"
+" */\n"
+"Object removeObject(Fqn fqn) throws CacheException;"
#. Tag: para
#: Api.xml:28
@@ -170,6 +187,15 @@
" */\n"
"Object getObject(Fqn fqn) throws CacheException;"
msgstr ""
+"/**\n"
+" * Retrieve the Pojo from the cache. Return null if object does not exist "
+"in the cache.\n"
+" *\n"
+" * @param fqn Instance that associates with this node.\n"
+" * @return Current POJO value. Null if does not exist.\n"
+" * @throws CacheException\n"
+" */\n"
+"Object getObject(Fqn fqn) throws CacheException;"
#. Tag: para
#: Api.xml:33
@@ -205,6 +231,22 @@
" */\n"
"public Map findObjects(Fqn fqn) throws CacheException;"
msgstr ""
+"/**\n"
+" * Query all managed pojo objects under the fqn recursively. Note that this "
+"will not return \n"
+" *the sub-object POJOs, e.g., if Person has a sub-object of Address, it "
+"won't return Address \n"
+" *pojo. Note also that this operation is not thread-safe now. In addition, "
+"it assumes \n"
+" *that once a pojo is found with a fqn, no more pojo is stored under the "
+"children of the fqn. \n"
+" *That is, we don't mixed the fqn with different POJOs.\n"
+" * @param fqn The starting place to find all POJOs.\n"
+" * @return Map of all POJOs found with (fqn, pojo) pair. Return size of 0, "
+"if not found.\n"
+" * @throws CacheException\n"
+" */\n"
+"public Map findObjects(Fqn fqn) throws CacheException;"
#. Tag: para
#: Api.xml:37
15 years, 9 months
JBoss Cache SVN: r7916 - enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE.
by jbosscache-commits@lists.jboss.org
Author: jdimanos(a)jboss.com
Date: 2009-03-19 03:30:26 -0400 (Thu, 19 Mar 2009)
New Revision: 7916
Modified:
enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Api.po
Log:
update
Modified: enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Api.po
===================================================================
--- enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Api.po 2009-03-18 16:38:48 UTC (rev 7915)
+++ enterprise-docs/tags/JBoss_EAP_4_3/Cache_Pojo_Cache_Guide/de-DE/Api.po 2009-03-19 07:30:26 UTC (rev 7916)
@@ -1,24 +1,26 @@
+# translation of Api.po to
# Language /tmp/mike/JBEAP420/Cache translations for JBEAP package.
-# Copyright (C) 2007 Free Software Foundation, Inc.
+# Copyright (C) 2007, 2009 Free Software Foundation, Inc.
# Automatically generated, 2007.
#
msgid ""
msgstr ""
-"Project-Id-Version: JBEAP 420\n"
+"Project-Id-Version: Api\n"
"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
"POT-Creation-Date: 2008-09-21 04:57+0000\n"
-"PO-Revision-Date: 2001-02-09 01:25+0100\n"
-"Last-Translator: Automatically generated\n"
-"Language-Team: none\n"
+"PO-Revision-Date: 2009-03-19 18:29+1100\n"
+"Last-Translator: \n"
+"Language-Team: <en(a)li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
#. Tag: title
#: Api.xml:5
#, no-c-format
msgid "<title>API</title>"
-msgstr ""
+msgstr "<title>API</title>"
#. Tag: para
#: Api.xml:6
@@ -224,3 +226,4 @@
"the children of the fqn. That is, we don't mixed the fqn with different "
"POJOs."
msgstr ""
+
15 years, 9 months
JBoss Cache SVN: r7915 - in core/trunk/src/main/java/org/jboss/cache: mvcc and 1 other directory.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-03-18 12:38:48 -0400 (Wed, 18 Mar 2009)
New Revision: 7915
Modified:
core/trunk/src/main/java/org/jboss/cache/AbstractNode.java
core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java
Log:
JBCACHE-1496 - Typo in ReadCommittedNode.Flags.ORIG_CHILDREN_LOADED enum mask
Modified: core/trunk/src/main/java/org/jboss/cache/AbstractNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/AbstractNode.java 2009-03-18 15:48:28 UTC (rev 7914)
+++ core/trunk/src/main/java/org/jboss/cache/AbstractNode.java 2009-03-18 16:38:48 UTC (rev 7915)
@@ -59,47 +59,47 @@
/**
* All children are loaded from the cache loader if this flag is present.
*/
- CHILDREN_LOADED(0x1),
+ CHILDREN_LOADED(1),
/**
* Data is loaded from the cache loader if this flag is present.
*/
- DATA_LOADED(0x2),
+ DATA_LOADED(1<<1),
/**
* Node is write-locked when children are added or removed if this flag is enabled.
*/
- LOCK_FOR_CHILD_INSERT_REMOVE(0x4),
+ LOCK_FOR_CHILD_INSERT_REMOVE(1<<2),
/**
* Node is valid if this flag is present.
*/
- VALID(0x8),
+ VALID(1<<3),
/**
* Node has been removed.
*/
- REMOVED(0x10),
+ REMOVED(1<<4),
/**
* NOde is resident and excluded from evictions
*/
- RESIDENT(0x20),
+ RESIDENT(1<<5),
/**
* Specific to Optimistic Locking Workspace nodes - set if a node has been modified in a workspace.
*/
- MODIFIED_IN_WORKSPACE(0x40),
+ MODIFIED_IN_WORKSPACE(1<<6),
/**
* Specific to Optimistic Locking Workspace nodes - set if a node has been created in a workspace.
*/
- CREATED_IN_WORKSPACE(0x80),
+ CREATED_IN_WORKSPACE(1<<7),
/**
* Specific to Optimistic Locking Workspace nodes - set if a node has added or removed children in a workspace.
*/
- CHILDREN_MODIFIED_IN_WORKSPACE(0x100),
+ CHILDREN_MODIFIED_IN_WORKSPACE(1<<8),
/**
* Specific to Optimistic Locking Workspace nodes - set if an implicit version is associated with this node.
*/
- VERSIONING_IMPLICIT(0x200),
+ VERSIONING_IMPLICIT(1<<9),
/**
* Specific to Optimistic Locking Workspace nodes - set if a node has been resurrected in a workspace.
*/
- RESURRECTED_IN_WORKSPACE(0x400);
+ RESURRECTED_IN_WORKSPACE(1<<10);
protected final short mask;
Modified: core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java 2009-03-18 15:48:28 UTC (rev 7914)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java 2009-03-18 16:38:48 UTC (rev 7915)
@@ -50,7 +50,7 @@
protected static enum Flags
{
- CHANGED(0x1), CREATED(0x2), DELETED(0x4), ORIG_DATA_LOADED(0x8), ORIG_CHILDREN_LOADED(0x16);
+ CHANGED(1), CREATED(1<<1), DELETED(1<<2), ORIG_DATA_LOADED(1<<3), ORIG_CHILDREN_LOADED(1<<4);
final byte mask;
Flags(int mask)
15 years, 9 months
JBoss Cache SVN: r7914 - in core/branches/flat/src: main/java/org/horizon/config/parsing and 8 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-03-18 11:48:28 -0400 (Wed, 18 Mar 2009)
New Revision: 7914
Added:
core/branches/flat/src/main/java/org/horizon/lock/LockManagerImpl.java
core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/
core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractPerEntryLockContainer.java
core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractStripedLockContainer.java
core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/LockContainer.java
core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/OwnableReentrantPerEntryLockContainer.java
core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/OwnableReentrantStripedLockContainer.java
core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/ReentrantPerEntryLockContainer.java
core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/ReentrantStripedLockContainer.java
core/branches/flat/src/test/java/org/horizon/api/mvcc/LockPerEntryTest.java
Removed:
core/branches/flat/src/main/java/org/horizon/lock/StripedLockManager.java
core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/LockContainer.java
core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/OwnableReentrantLockContainer.java
core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/ReentrantLockContainer.java
Modified:
core/branches/flat/src/main/java/org/horizon/config/Configuration.java
core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java
core/branches/flat/src/main/java/org/horizon/factories/LockManagerFactory.java
core/branches/flat/src/main/resources/schema/horizon-config-1.0.xsd
core/branches/flat/src/test/java/org/horizon/api/mvcc/LockAssert.java
core/branches/flat/src/test/java/org/horizon/api/tree/TreeStructureHashCodeTest.java
core/branches/flat/src/test/java/org/horizon/lock/LockContainerHashingTest.java
Log:
HORIZON-40 - Create a lock-per-entry lock manager
Modified: core/branches/flat/src/main/java/org/horizon/config/Configuration.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/Configuration.java 2009-03-18 14:56:14 UTC (rev 7913)
+++ core/branches/flat/src/main/java/org/horizon/config/Configuration.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -44,6 +44,7 @@
// reference to a global configuration
private GlobalConfiguration globalConfiguration;
private String JmxNameBase;
+ private boolean useLockStriping = true;
public GlobalConfiguration getGlobalConfiguration() {
@@ -82,6 +83,15 @@
return JmxNameBase;
}
+ public void setUseLockStriping(boolean useLockStriping) {
+ testImmutability("useLockStriping");
+ this.useLockStriping = useLockStriping;
+ }
+
+ public boolean isUseLockStriping() {
+ return useLockStriping;
+ }
+
/**
* Cache replication mode.
*/
Modified: core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java 2009-03-18 14:56:14 UTC (rev 7913)
+++ core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -294,7 +294,7 @@
String jmxNameBase = getAttributeValue(element, "jmxNameBase");
if (existsAttribute(jmxNameBase)) {
config.setJmxNameBase(jmxNameBase);
- }
+ }
}
}
@@ -344,6 +344,8 @@
if (existsAttribute(lockAcquisitionTimeout)) config.setLockAcquisitionTimeout(getLong(lockAcquisitionTimeout));
String writeSkewCheck = getAttributeValue(element, "writeSkewCheck");
if (existsAttribute(writeSkewCheck)) config.setWriteSkewCheck(getBoolean(writeSkewCheck));
+ String useLockStriping = getAttributeValue(element, "useLockStriping");
+ if (existsAttribute(useLockStriping)) config.setUseLockStriping(getBoolean(useLockStriping));
String concurrencyLevel = getAttributeValue(element, "concurrencyLevel");
if (existsAttribute(concurrencyLevel)) config.setConcurrencyLevel(getInt(concurrencyLevel));
}
Modified: core/branches/flat/src/main/java/org/horizon/factories/LockManagerFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/LockManagerFactory.java 2009-03-18 14:56:14 UTC (rev 7913)
+++ core/branches/flat/src/main/java/org/horizon/factories/LockManagerFactory.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -23,7 +23,7 @@
import org.horizon.factories.annotations.DefaultFactoryFor;
import org.horizon.lock.LockManager;
-import org.horizon.lock.StripedLockManager;
+import org.horizon.lock.LockManagerImpl;
/**
* // TODO: MANIK: Document this
@@ -34,6 +34,6 @@
@DefaultFactoryFor(classes = LockManager.class)
public class LockManagerFactory extends AbstractComponentFactory implements AutoInstantiableFactory {
public <T> T construct(Class<T> componentType) {
- return (T) new StripedLockManager();
+ return (T) new LockManagerImpl();
}
}
Copied: core/branches/flat/src/main/java/org/horizon/lock/LockManagerImpl.java (from rev 7909, core/branches/flat/src/main/java/org/horizon/lock/StripedLockManager.java)
===================================================================
--- core/branches/flat/src/main/java/org/horizon/lock/LockManagerImpl.java (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/lock/LockManagerImpl.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -0,0 +1,148 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt 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.horizon.lock;
+
+import org.horizon.config.Configuration;
+import org.horizon.container.MVCCEntry;
+import org.horizon.context.InvocationContext;
+import org.horizon.factories.annotations.Inject;
+import org.horizon.factories.annotations.Start;
+import org.horizon.invocation.InvocationContextContainer;
+import org.horizon.invocation.Options;
+import org.horizon.logging.Log;
+import org.horizon.logging.LogFactory;
+import org.horizon.util.ReversibleOrderedSet;
+import org.horizon.util.concurrent.locks.OwnableReentrantLock;
+import org.horizon.util.concurrent.locks.containers.LockContainer;
+import org.horizon.util.concurrent.locks.containers.OwnableReentrantPerEntryLockContainer;
+import org.horizon.util.concurrent.locks.containers.OwnableReentrantStripedLockContainer;
+import org.horizon.util.concurrent.locks.containers.ReentrantPerEntryLockContainer;
+import org.horizon.util.concurrent.locks.containers.ReentrantStripedLockContainer;
+
+import javax.transaction.TransactionManager;
+import java.util.Iterator;
+import java.util.Map;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * Handles locks for the MVCC based LockingInterceptor
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @since 1.0
+ */
+public class LockManagerImpl implements LockManager {
+ protected Configuration configuration;
+ LockContainer lockContainer;
+ private TransactionManager transactionManager;
+ private InvocationContextContainer invocationContextContainer;
+ private static final Log log = LogFactory.getLog(LockManagerImpl.class);
+ private static final boolean trace = log.isTraceEnabled();
+
+ @Inject
+ public void injectDependencies(Configuration configuration, TransactionManager transactionManager, InvocationContextContainer invocationContextContainer) {
+ this.configuration = configuration;
+ this.transactionManager = transactionManager;
+ this.invocationContextContainer = invocationContextContainer;
+ }
+
+ @Start
+ public void startLockManager() {
+ lockContainer = configuration.isUseLockStriping() ?
+ transactionManager == null ? new ReentrantStripedLockContainer(configuration.getConcurrencyLevel()) : new OwnableReentrantStripedLockContainer(configuration.getConcurrencyLevel(), invocationContextContainer) :
+ transactionManager == null ? new ReentrantPerEntryLockContainer() : new OwnableReentrantPerEntryLockContainer(invocationContextContainer);
+ }
+
+ public Object getLockOwner(InvocationContext ctx) {
+ return ctx.getGlobalTransaction() != null ? ctx.getGlobalTransaction() : Thread.currentThread();
+ }
+
+ public boolean lockAndRecord(Object key, InvocationContext ctx) throws InterruptedException {
+ long lockTimeout = getLockAcquisitionTimeout(ctx);
+ if (trace) log.trace("Attempting to lock {0} with acquisition timeout of {1} millis", key, lockTimeout);
+ if (lockContainer.acquireLock(key, lockTimeout, MILLISECONDS)) {
+ ctx.setContainsLocks(true);
+ return true;
+ }
+
+ // couldn't acquire lock!
+ return false;
+ }
+
+ private long getLockAcquisitionTimeout(InvocationContext ctx) {
+ return ctx.hasOption(Options.ZERO_LOCK_ACQUISITION_TIMEOUT) ?
+ 0 : configuration.getLockAcquisitionTimeout();
+ }
+
+ public void unlock(Object key, Object owner) {
+ if (trace) log.trace("Attempting to unlock " + key);
+ lockContainer.releaseLock(key);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void unlock(InvocationContext ctx) {
+ ReversibleOrderedSet<Map.Entry<Object, MVCCEntry>> entries = ctx.getLookedUpEntries().entrySet();
+ if (!entries.isEmpty()) {
+ // unlocking needs to be done in reverse order.
+ Iterator<Map.Entry<Object, MVCCEntry>> it = entries.reverseIterator();
+ while (it.hasNext()) {
+ Map.Entry<Object, MVCCEntry> e = it.next();
+ MVCCEntry entry = e.getValue();
+ if (possiblyLocked(entry)) {
+ // has been locked!
+ Object k = e.getKey();
+ if (trace) log.trace("Attempting to unlock " + k);
+ lockContainer.releaseLock(k);
+ }
+ }
+ }
+ }
+
+ public boolean ownsLock(Object key, Object owner) {
+ return lockContainer.ownsLock(key, owner);
+ }
+
+ public boolean isLocked(Object key) {
+ return lockContainer.isLocked(key);
+ }
+
+ public Object getOwner(Object key) {
+ if (lockContainer.isLocked(key)) {
+ Lock l = lockContainer.getLock(key);
+
+ if (l instanceof OwnableReentrantLock) {
+ return ((OwnableReentrantLock) l).getOwner();
+ } else {
+ // cannot determine owner.
+ return null;
+ }
+ } else return null;
+ }
+
+ public String printLockInfo() {
+ return lockContainer.toString();
+ }
+
+ public final boolean possiblyLocked(MVCCEntry entry) {
+ return entry == null || entry.isChanged() || entry.isNullEntry();
+ }
+}
Property changes on: core/branches/flat/src/main/java/org/horizon/lock/LockManagerImpl.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Deleted: core/branches/flat/src/main/java/org/horizon/lock/StripedLockManager.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/lock/StripedLockManager.java 2009-03-18 14:56:14 UTC (rev 7913)
+++ core/branches/flat/src/main/java/org/horizon/lock/StripedLockManager.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -1,146 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt 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.horizon.lock;
-
-import org.horizon.config.Configuration;
-import org.horizon.container.MVCCEntry;
-import org.horizon.context.InvocationContext;
-import org.horizon.factories.annotations.Inject;
-import org.horizon.factories.annotations.Start;
-import org.horizon.invocation.InvocationContextContainer;
-import org.horizon.invocation.Options;
-import org.horizon.logging.Log;
-import org.horizon.logging.LogFactory;
-import org.horizon.util.ReversibleOrderedSet;
-import org.horizon.util.concurrent.locks.LockContainer;
-import org.horizon.util.concurrent.locks.OwnableReentrantLock;
-import org.horizon.util.concurrent.locks.OwnableReentrantLockContainer;
-import org.horizon.util.concurrent.locks.ReentrantLockContainer;
-
-import javax.transaction.TransactionManager;
-import java.util.Iterator;
-import java.util.Map;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import java.util.concurrent.locks.Lock;
-
-/**
- * Handles locks for the MVCC based LockingInterceptor
- *
- * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
- * @since 1.0
- */
-public class StripedLockManager implements LockManager {
- protected Configuration configuration;
- LockContainer<Object> lockContainer;
- private TransactionManager transactionManager;
- private InvocationContextContainer invocationContextContainer;
- private static final Log log = LogFactory.getLog(StripedLockManager.class);
- private static final boolean trace = log.isTraceEnabled();
-
- @Inject
- public void injectDependencies(Configuration configuration, TransactionManager transactionManager, InvocationContextContainer invocationContextContainer) {
- this.configuration = configuration;
- this.transactionManager = transactionManager;
- this.invocationContextContainer = invocationContextContainer;
- }
-
- @Start
- public void startLockManager() {
- lockContainer = transactionManager == null ? new ReentrantLockContainer<Object>(configuration.getConcurrencyLevel()) : new OwnableReentrantLockContainer<Object>(configuration.getConcurrencyLevel(), invocationContextContainer);
- }
-
- public Object getLockOwner(InvocationContext ctx) {
- return ctx.getGlobalTransaction() != null ? ctx.getGlobalTransaction() : Thread.currentThread();
- }
-
- public boolean lockAndRecord(Object key, InvocationContext ctx) throws InterruptedException {
- long lockTimeout = getLockAcquisitionTimeout(ctx);
- if (trace) log.trace("Attempting to lock {0} with acquisition timeout of {1} millis", key, lockTimeout);
- Lock lock = lockContainer.getLock(key);
- if (lock.tryLock(lockTimeout, MILLISECONDS)) {
- ctx.setContainsLocks(true);
- return true;
- }
-
- // couldn't acquire lock!
- return false;
- }
-
- private long getLockAcquisitionTimeout(InvocationContext ctx) {
- return ctx.hasOption(Options.ZERO_LOCK_ACQUISITION_TIMEOUT) ?
- 0 : configuration.getLockAcquisitionTimeout();
- }
-
- public void unlock(Object key, Object owner) {
- if (trace) log.trace("Attempting to unlock " + key);
- Lock lock = lockContainer.getLock(key);
- lock.unlock();
- }
-
- @SuppressWarnings("unchecked")
- public void unlock(InvocationContext ctx) {
- ReversibleOrderedSet<Map.Entry<Object, MVCCEntry>> entries = ctx.getLookedUpEntries().entrySet();
- if (!entries.isEmpty()) {
- // unlocking needs to be done in reverse order.
- Iterator<Map.Entry<Object, MVCCEntry>> it = entries.reverseIterator();
- while (it.hasNext()) {
- Map.Entry<Object, MVCCEntry> e = it.next();
- MVCCEntry entry = e.getValue();
- if (possiblyLocked(entry)) {
- // has been locked!
- Object k = e.getKey();
- if (trace) log.trace("Attempting to unlock " + k);
- lockContainer.getLock(k).unlock();
- }
- }
- }
- }
-
- public boolean ownsLock(Object key, Object owner) {
- return lockContainer.ownsLock(key, owner);
- }
-
- public boolean isLocked(Object key) {
- return lockContainer.isLocked(key);
- }
-
- public Object getOwner(Object key) {
- if (lockContainer.isLocked(key)) {
- Lock l = lockContainer.getLock(key);
-
- if (l instanceof OwnableReentrantLock) {
- return ((OwnableReentrantLock) l).getOwner();
- } else {
- // cannot determine owner.
- return null;
- }
- } else return null;
- }
-
- public String printLockInfo() {
- return lockContainer.toString();
- }
-
- public final boolean possiblyLocked(MVCCEntry entry) {
- return entry == null || entry.isChanged() || entry.isNullEntry();
- }
-}
Deleted: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/LockContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/LockContainer.java 2009-03-18 14:56:14 UTC (rev 7913)
+++ core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/LockContainer.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -1,113 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 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.horizon.util.concurrent.locks;
-
-import net.jcip.annotations.ThreadSafe;
-
-import java.util.concurrent.locks.Lock;
-
-/**
- * A container for locks. Used with lock striping.
- *
- * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
- * @since 1.0
- */
-@ThreadSafe
-public abstract class LockContainer<E> {
- private int lockSegmentMask;
- private int lockSegmentShift;
-
-
- protected int calculateNumberOfSegments(int concurrencyLevel) {
- int tempLockSegShift = 0;
- int numLocks = 1;
- while (numLocks < concurrencyLevel) {
- ++tempLockSegShift;
- numLocks <<= 1;
- }
- lockSegmentShift = 32 - tempLockSegShift;
- lockSegmentMask = numLocks - 1;
- return numLocks;
- }
-
- public final int hashToIndex(E object) {
- return (hash(object) >>> lockSegmentShift) & lockSegmentMask;
- }
-
- /**
- * Returns a hash code for non-null Object x. Uses the same hash code spreader as most other java.util hash tables,
- * except that this uses the string representation of the object passed in.
- *
- * @param object the object serving as a key
- * @return the hash code
- */
- final int hash(E object) {
- int h = object.hashCode();
-// h ^= (h >>> 20) ^ (h >>> 12);
-// return h ^ (h >>> 7) ^ (h >>> 4);
-
- h += ~(h << 9);
- h ^= (h >>> 14);
- h += (h << 4);
- h ^= (h >>> 10);
- return h;
-
- }
-
- protected abstract void initLocks(int numLocks);
-
- /**
- * Tests if a give owner owns a lock on a specified object.
- *
- * @param object object to check
- * @param owner owner to test
- * @return true if owner owns lock, false otherwise
- */
- public abstract boolean ownsLock(E object, Object owner);
-
- /**
- * @param object object
- * @return true if an object is locked, false otherwise
- */
- public abstract boolean isLocked(E object);
-
- /**
- * @param object object
- * @return the lock for a specific object
- */
- public abstract Lock getLock(E object);
-
- /**
- * @return number of locks held
- */
- public abstract int getNumLocksHeld();
-
- /**
- * @return the size of the shared lock pool
- */
- public abstract int size();
-
- /**
- * Clears all locks held and re-initialises stripes.
- */
- public abstract void reset();
-}
Deleted: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/OwnableReentrantLockContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/OwnableReentrantLockContainer.java 2009-03-18 14:56:14 UTC (rev 7913)
+++ core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/OwnableReentrantLockContainer.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -1,93 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 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.horizon.util.concurrent.locks;
-
-import net.jcip.annotations.ThreadSafe;
-import org.horizon.invocation.InvocationContextContainer;
-
-import java.util.Arrays;
-
-/**
- * A LockContainer that holds {@link org.horizon.util.concurrent.locks.OwnableReentrantLock}s.
- *
- * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
- * @see org.horizon.util.concurrent.locks.ReentrantLockContainer
- * @see org.horizon.util.concurrent.locks.OwnableReentrantLock
- * @since 1.0
- */
-@ThreadSafe
-public class OwnableReentrantLockContainer<E> extends LockContainer<E> {
- OwnableReentrantLock[] sharedLocks;
- InvocationContextContainer icc;
-
- /**
- * Creates a new LockContainer which uses a certain number of shared locks across all elements that need to be
- * locked.
- *
- * @param concurrencyLevel concurrency level for number of stripes to create. Stripes are created in powers of two,
- * with a minimum of concurrencyLevel created.
- * @param icc invocation context container to use
- */
- public OwnableReentrantLockContainer(int concurrencyLevel, InvocationContextContainer icc) {
- this.icc = icc;
- initLocks(calculateNumberOfSegments(concurrencyLevel));
- }
-
- protected void initLocks(int numLocks) {
- sharedLocks = new OwnableReentrantLock[numLocks];
- for (int i = 0; i < numLocks; i++) sharedLocks[i] = new OwnableReentrantLock(icc);
- }
-
- public final OwnableReentrantLock getLock(E object) {
- return sharedLocks[hashToIndex(object)];
- }
-
- public final boolean ownsLock(E object, Object owner) {
- OwnableReentrantLock lock = getLock(object);
- return owner.equals(lock.getOwner());
- }
-
- public final boolean isLocked(E object) {
- OwnableReentrantLock lock = getLock(object);
- return lock.isLocked();
- }
-
- public final int getNumLocksHeld() {
- int i = 0;
- for (OwnableReentrantLock l : sharedLocks) if (l.isLocked()) i++;
- return i;
- }
-
- public String toString() {
- return "OwnableReentrantLockContainer{" +
- "sharedLocks=" + (sharedLocks == null ? null : Arrays.asList(sharedLocks)) +
- '}';
- }
-
- public void reset() {
- initLocks(sharedLocks.length);
- }
-
- public int size() {
- return sharedLocks.length;
- }
-}
Deleted: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/ReentrantLockContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/ReentrantLockContainer.java 2009-03-18 14:56:14 UTC (rev 7913)
+++ core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/ReentrantLockContainer.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -1,89 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 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.horizon.util.concurrent.locks;
-
-import net.jcip.annotations.ThreadSafe;
-
-import java.util.Arrays;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * A LockContainer that holds ReentrantLocks
- *
- * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
- * @see org.horizon.util.concurrent.locks.OwnableReentrantLockContainer
- * @since 1.0
- */
-@ThreadSafe
-public class ReentrantLockContainer<E> extends LockContainer<E> {
- ReentrantLock[] sharedLocks;
-
- /**
- * Creates a new LockContainer which uses a certain number of shared locks across all elements that need to be
- * locked.
- *
- * @param concurrencyLevel concurrency level for number of stripes to create. Stripes are created in powers of two,
- * with a minimum of concurrencyLevel created.
- */
- public ReentrantLockContainer(int concurrencyLevel) {
- initLocks(calculateNumberOfSegments(concurrencyLevel));
- }
-
- protected void initLocks(int numLocks) {
- sharedLocks = new ReentrantLock[numLocks];
- for (int i = 0; i < numLocks; i++) sharedLocks[i] = new ReentrantLock();
- }
-
- public final ReentrantLock getLock(E object) {
- return sharedLocks[hashToIndex(object)];
- }
-
- public final int getNumLocksHeld() {
- int i = 0;
- for (ReentrantLock l : sharedLocks) if (l.isLocked()) i++;
- return i;
- }
-
- public int size() {
- return sharedLocks.length;
- }
-
- public final boolean ownsLock(E object, Object owner) {
- ReentrantLock lock = getLock(object);
- return lock.isHeldByCurrentThread();
- }
-
- public final boolean isLocked(E object) {
- ReentrantLock lock = getLock(object);
- return lock.isLocked();
- }
-
- public String toString() {
- return "ReentrantLockContainer{" +
- "sharedLocks=" + (sharedLocks == null ? null : Arrays.asList(sharedLocks)) +
- '}';
- }
-
- public void reset() {
- initLocks(sharedLocks.length);
- }
-}
Added: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractPerEntryLockContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractPerEntryLockContainer.java (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractPerEntryLockContainer.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -0,0 +1,49 @@
+package org.horizon.util.concurrent.locks.containers;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * An abstract lock container that creates and maintains a new lock per entry
+ *
+ * @author Manik Surtani
+ * @since 1.0
+ */
+public abstract class AbstractPerEntryLockContainer implements LockContainer {
+
+ ConcurrentMap<Object, Lock> locks = new ConcurrentHashMap<Object, Lock>();
+
+ protected abstract Lock newLock();
+
+ public Lock getLock(Object key) {
+ Lock l = newLock();
+ Lock tmp = locks.putIfAbsent(key, l);
+ if (tmp != null) l = tmp;
+ return l;
+ }
+
+ public int getNumLocksHeld() {
+ return locks.size();
+ }
+
+ public int size() {
+ return locks.size();
+ }
+
+ public boolean acquireLock(Object key, long timeout, TimeUnit unit) throws InterruptedException {
+ Lock l = getLock(key);
+ boolean success = l.tryLock(timeout, unit);
+ if (l != locks.get(key)) {
+ l.unlock();
+ success = acquireLock(key, timeout, unit); // todo avoid recursion here, this could get ugly!
+ }
+ return success;
+ }
+
+ public void releaseLock(Object key) {
+ Lock l = locks.remove(key);
+ if (l != null) l.unlock();
+ }
+}
Copied: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractStripedLockContainer.java (from rev 7909, core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/LockContainer.java)
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractStripedLockContainer.java (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractStripedLockContainer.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -0,0 +1,85 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 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.horizon.util.concurrent.locks.containers;
+
+import net.jcip.annotations.ThreadSafe;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A container for locks. Used with lock striping.
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @since 1.0
+ */
+@ThreadSafe
+public abstract class AbstractStripedLockContainer implements LockContainer {
+ private int lockSegmentMask;
+ private int lockSegmentShift;
+
+
+ final int calculateNumberOfSegments(int concurrencyLevel) {
+ int tempLockSegShift = 0;
+ int numLocks = 1;
+ while (numLocks < concurrencyLevel) {
+ ++tempLockSegShift;
+ numLocks <<= 1;
+ }
+ lockSegmentShift = 32 - tempLockSegShift;
+ lockSegmentMask = numLocks - 1;
+ return numLocks;
+ }
+
+ final int hashToIndex(Object object) {
+ return (hash(object) >>> lockSegmentShift) & lockSegmentMask;
+ }
+
+ /**
+ * Returns a hash code for non-null Object x. Uses the same hash code spreader as most other java.util hash tables,
+ * except that this uses the string representation of the object passed in.
+ *
+ * @param object the object serving as a key
+ * @return the hash code
+ */
+ final int hash(Object object) {
+ int h = object.hashCode();
+// h ^= (h >>> 20) ^ (h >>> 12);
+// return h ^ (h >>> 7) ^ (h >>> 4);
+
+ h += ~(h << 9);
+ h ^= (h >>> 14);
+ h += (h << 4);
+ h ^= (h >>> 10);
+ return h;
+
+ }
+
+ protected abstract void initLocks(int numLocks);
+
+ public boolean acquireLock(Object key, long timeout, TimeUnit unit) throws InterruptedException {
+ return getLock(key).tryLock(timeout, unit);
+ }
+
+ public void releaseLock(Object key) {
+ getLock(key).unlock();
+ }
+}
Property changes on: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/AbstractStripedLockContainer.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/LockContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/LockContainer.java (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/LockContainer.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -0,0 +1,47 @@
+package org.horizon.util.concurrent.locks.containers;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * A container for locks
+ *
+ * @author Manik Surtani
+ * @since 1.0
+ */
+public interface LockContainer {
+ /**
+ * Tests if a give owner owns a lock on a specified object.
+ *
+ * @param key object to check
+ * @param owner owner to test
+ * @return true if owner owns lock, false otherwise
+ */
+ boolean ownsLock(Object key, Object owner);
+
+ /**
+ * @param key object
+ * @return true if an object is locked, false otherwise
+ */
+ boolean isLocked(Object key);
+
+ /**
+ * @param key object
+ * @return the lock for a specific object
+ */
+ Lock getLock(Object key);
+
+ /**
+ * @return number of locks held
+ */
+ int getNumLocksHeld();
+
+ /**
+ * @return the size of the shared lock pool
+ */
+ int size();
+
+ boolean acquireLock(Object key, long timeout, TimeUnit unit) throws InterruptedException;
+
+ void releaseLock(Object key);
+}
Added: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/OwnableReentrantPerEntryLockContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/OwnableReentrantPerEntryLockContainer.java (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/OwnableReentrantPerEntryLockContainer.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -0,0 +1,39 @@
+package org.horizon.util.concurrent.locks.containers;
+
+import org.horizon.invocation.InvocationContextContainer;
+import org.horizon.util.concurrent.locks.OwnableReentrantLock;
+
+import java.util.concurrent.locks.Lock;
+
+/**
+ * // TODO: Manik: Document this!
+ *
+ * @author Manik Surtani
+ * @since 1.0
+ */
+public class OwnableReentrantPerEntryLockContainer extends AbstractPerEntryLockContainer {
+
+ private InvocationContextContainer icc;
+
+ public OwnableReentrantPerEntryLockContainer(InvocationContextContainer icc) {
+ this.icc = icc;
+ }
+
+ protected Lock newLock() {
+ return new OwnableReentrantLock(icc);
+ }
+
+ public boolean ownsLock(Object key, Object owner) {
+ OwnableReentrantLock l = getLockFromMap(key);
+ return l != null && owner.equals(l.getOwner());
+ }
+
+ public boolean isLocked(Object key) {
+ OwnableReentrantLock l = getLockFromMap(key);
+ return l != null && l.isLocked();
+ }
+
+ private OwnableReentrantLock getLockFromMap(Object key) {
+ return (OwnableReentrantLock) locks.get(key);
+ }
+}
Copied: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/OwnableReentrantStripedLockContainer.java (from rev 7909, core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/OwnableReentrantLockContainer.java)
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/OwnableReentrantStripedLockContainer.java (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/OwnableReentrantStripedLockContainer.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 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.horizon.util.concurrent.locks.containers;
+
+import net.jcip.annotations.ThreadSafe;
+import org.horizon.invocation.InvocationContextContainer;
+import org.horizon.util.concurrent.locks.OwnableReentrantLock;
+
+import java.util.Arrays;
+
+/**
+ * A LockContainer that holds {@link org.horizon.util.concurrent.locks.OwnableReentrantLock}s.
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @see ReentrantStripedLockContainer
+ * @see org.horizon.util.concurrent.locks.OwnableReentrantLock
+ * @since 1.0
+ */
+@ThreadSafe
+public class OwnableReentrantStripedLockContainer extends AbstractStripedLockContainer {
+ OwnableReentrantLock[] sharedLocks;
+ InvocationContextContainer icc;
+
+ /**
+ * Creates a new LockContainer which uses a certain number of shared locks across all elements that need to be
+ * locked.
+ *
+ * @param concurrencyLevel concurrency level for number of stripes to create. Stripes are created in powers of two,
+ * with a minimum of concurrencyLevel created.
+ * @param icc invocation context container to use
+ */
+ public OwnableReentrantStripedLockContainer(int concurrencyLevel, InvocationContextContainer icc) {
+ this.icc = icc;
+ initLocks(calculateNumberOfSegments(concurrencyLevel));
+ }
+
+ protected void initLocks(int numLocks) {
+ sharedLocks = new OwnableReentrantLock[numLocks];
+ for (int i = 0; i < numLocks; i++) sharedLocks[i] = new OwnableReentrantLock(icc);
+ }
+
+ public final OwnableReentrantLock getLock(Object object) {
+ return sharedLocks[hashToIndex(object)];
+ }
+
+ public final boolean ownsLock(Object object, Object owner) {
+ OwnableReentrantLock lock = getLock(object);
+ return owner.equals(lock.getOwner());
+ }
+
+ public final boolean isLocked(Object object) {
+ OwnableReentrantLock lock = getLock(object);
+ return lock.isLocked();
+ }
+
+ public final int getNumLocksHeld() {
+ int i = 0;
+ for (OwnableReentrantLock l : sharedLocks) if (l.isLocked()) i++;
+ return i;
+ }
+
+ public String toString() {
+ return "OwnableReentrantStripedLockContainer{" +
+ "sharedLocks=" + (sharedLocks == null ? null : Arrays.asList(sharedLocks)) +
+ '}';
+ }
+
+ public int size() {
+ return sharedLocks.length;
+ }
+}
Property changes on: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/OwnableReentrantStripedLockContainer.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/ReentrantPerEntryLockContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/ReentrantPerEntryLockContainer.java (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/ReentrantPerEntryLockContainer.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -0,0 +1,31 @@
+package org.horizon.util.concurrent.locks.containers;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * // TODO: Manik: Document this!
+ *
+ * @author Manik Surtani
+ * @since 1.0
+ */
+public class ReentrantPerEntryLockContainer extends AbstractPerEntryLockContainer {
+
+ protected Lock newLock() {
+ return new ReentrantLock();
+ }
+
+ public boolean ownsLock(Object key, Object owner) {
+ ReentrantLock l = getLockFromMap(key);
+ return l != null && l.isHeldByCurrentThread();
+ }
+
+ public boolean isLocked(Object key) {
+ ReentrantLock l = getLockFromMap(key);
+ return l != null && l.isLocked();
+ }
+
+ private ReentrantLock getLockFromMap(Object key) {
+ return (ReentrantLock) locks.get(key);
+ }
+}
Copied: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/ReentrantStripedLockContainer.java (from rev 7909, core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/ReentrantLockContainer.java)
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/ReentrantStripedLockContainer.java (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/ReentrantStripedLockContainer.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -0,0 +1,85 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 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.horizon.util.concurrent.locks.containers;
+
+import net.jcip.annotations.ThreadSafe;
+
+import java.util.Arrays;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * A LockContainer that holds ReentrantLocks
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @see OwnableReentrantStripedLockContainer
+ * @since 1.0
+ */
+@ThreadSafe
+public class ReentrantStripedLockContainer extends AbstractStripedLockContainer {
+ ReentrantLock[] sharedLocks;
+
+ /**
+ * Creates a new LockContainer which uses a certain number of shared locks across all elements that need to be
+ * locked.
+ *
+ * @param concurrencyLevel concurrency level for number of stripes to create. Stripes are created in powers of two,
+ * with a minimum of concurrencyLevel created.
+ */
+ public ReentrantStripedLockContainer(int concurrencyLevel) {
+ initLocks(calculateNumberOfSegments(concurrencyLevel));
+ }
+
+ protected void initLocks(int numLocks) {
+ sharedLocks = new ReentrantLock[numLocks];
+ for (int i = 0; i < numLocks; i++) sharedLocks[i] = new ReentrantLock();
+ }
+
+ public final ReentrantLock getLock(Object object) {
+ return sharedLocks[hashToIndex(object)];
+ }
+
+ public final int getNumLocksHeld() {
+ int i = 0;
+ for (ReentrantLock l : sharedLocks) if (l.isLocked()) i++;
+ return i;
+ }
+
+ public int size() {
+ return sharedLocks.length;
+ }
+
+ public final boolean ownsLock(Object object, Object owner) {
+ ReentrantLock lock = getLock(object);
+ return lock.isHeldByCurrentThread();
+ }
+
+ public final boolean isLocked(Object object) {
+ ReentrantLock lock = getLock(object);
+ return lock.isLocked();
+ }
+
+ public String toString() {
+ return "ReentrantStripedLockContainer{" +
+ "sharedLocks=" + (sharedLocks == null ? null : Arrays.asList(sharedLocks)) +
+ '}';
+ }
+}
Property changes on: core/branches/flat/src/main/java/org/horizon/util/concurrent/locks/containers/ReentrantStripedLockContainer.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: core/branches/flat/src/main/resources/schema/horizon-config-1.0.xsd
===================================================================
--- core/branches/flat/src/main/resources/schema/horizon-config-1.0.xsd 2009-03-18 14:56:14 UTC (rev 7913)
+++ core/branches/flat/src/main/resources/schema/horizon-config-1.0.xsd 2009-03-18 15:48:28 UTC (rev 7914)
@@ -84,6 +84,7 @@
</xs:attribute>
<xs:attribute name="lockAcquisitionTimeout" type="tns:positiveInteger"/>
<xs:attribute name="writeSkewCheck" type="tns:booleanType"/>
+ <xs:attribute name="useLockStriping" type="tns:booleanType"/>
<xs:attribute name="concurrencyLevel" type="xs:integer"/>
</xs:complexType>
Modified: core/branches/flat/src/test/java/org/horizon/api/mvcc/LockAssert.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/mvcc/LockAssert.java 2009-03-18 14:56:14 UTC (rev 7913)
+++ core/branches/flat/src/test/java/org/horizon/api/mvcc/LockAssert.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -4,7 +4,7 @@
import org.horizon.invocation.InvocationContextContainer;
import org.horizon.lock.LockManager;
import org.horizon.test.TestingUtil;
-import org.horizon.util.concurrent.locks.LockContainer;
+import org.horizon.util.concurrent.locks.containers.LockContainer;
/**
* Helper class to assert lock status in MVCC
Added: core/branches/flat/src/test/java/org/horizon/api/mvcc/LockPerEntryTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/mvcc/LockPerEntryTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/api/mvcc/LockPerEntryTest.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -0,0 +1,87 @@
+package org.horizon.api.mvcc;
+
+import org.horizon.Cache;
+import org.horizon.config.Configuration;
+import org.horizon.invocation.InvocationContextContainer;
+import org.horizon.lock.LockManager;
+import org.horizon.manager.CacheManager;
+import org.horizon.manager.DefaultCacheManager;
+import org.horizon.test.SingleCacheManagerTest;
+import org.horizon.test.TestingUtil;
+import org.horizon.util.concurrent.locks.containers.LockContainer;
+import org.testng.annotations.Test;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+@Test(groups = "functional", sequential = true, testName = "api.mvcc.LockPerEntryTest")
+public class LockPerEntryTest extends SingleCacheManagerTest {
+ Cache cache;
+
+ protected CacheManager createCacheManager() throws Exception {
+ Configuration cfg = new Configuration();
+ cfg.setUseLockStriping(false);
+ return new DefaultCacheManager(cfg);
+ }
+
+ public void testLocksCleanedUp() {
+ cache = cacheManager.getCache();
+ cache.put("/a/b/c", "v");
+ cache.put("/a/b/d", "v");
+ assertNoLocks();
+ }
+
+ public void testLocksConcurrency() throws Exception {
+ cache = cacheManager.getCache();
+ final int NUM_THREADS = 10;
+ final CountDownLatch l = new CountDownLatch(1);
+ final int numLoops = 1000;
+ final List<Exception> exceptions = new LinkedList<Exception>();
+
+ Thread[] t = new Thread[NUM_THREADS];
+ for (int i = 0; i < NUM_THREADS; i++)
+ t[i] = new Thread() {
+ public void run() {
+ try {
+ l.await();
+ }
+ catch (Exception e) {
+ // ignore
+ }
+ for (int i = 0; i < numLoops; i++) {
+ try {
+ switch (i % 2) {
+ case 0:
+ cache.put("Key" + i, "v");
+ break;
+ case 1:
+ cache.remove("Key" + i);
+ break;
+ }
+ }
+ catch (Exception e) {
+ exceptions.add(e);
+ }
+ }
+ }
+ };
+
+ for (Thread th : t) th.start();
+ l.countDown();
+ for (Thread th : t) th.join();
+
+ if (!exceptions.isEmpty()) throw exceptions.get(0);
+ assertNoLocks();
+ }
+
+ private void assertNoLocks() {
+ LockManager lm = TestingUtil.extractLockManager(cache);
+ LockAssert.assertNoLocks(
+ lm, TestingUtil.extractComponentRegistry(cache).getComponent(InvocationContextContainer.class)
+ );
+
+ LockContainer lc = (LockContainer) TestingUtil.extractField(lm, "lockContainer");
+ assert lc.size() == 0;
+ }
+}
Modified: core/branches/flat/src/test/java/org/horizon/api/tree/TreeStructureHashCodeTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/tree/TreeStructureHashCodeTest.java 2009-03-18 14:56:14 UTC (rev 7913)
+++ core/branches/flat/src/test/java/org/horizon/api/tree/TreeStructureHashCodeTest.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -2,8 +2,8 @@
import org.horizon.tree.Fqn;
import org.horizon.tree.NodeKey;
-import org.horizon.util.concurrent.locks.LockContainer;
-import org.horizon.util.concurrent.locks.ReentrantLockContainer;
+import org.horizon.util.concurrent.locks.containers.LockContainer;
+import org.horizon.util.concurrent.locks.containers.ReentrantStripedLockContainer;
import org.testng.annotations.Test;
import java.util.ArrayList;
@@ -15,7 +15,7 @@
/**
* Tests the degree to which hash codes get spread
*/
-@Test (groups = "unit" , testName = "api.tree.TreeStructureHashCodeTest")
+@Test(groups = "unit", testName = "api.tree.TreeStructureHashCodeTest")
public class TreeStructureHashCodeTest {
public void testHashCodesAppendedCount() {
@@ -33,7 +33,7 @@
}
private void doTest(List<Fqn> fqns) {
- LockContainer<NodeKey> container = new ReentrantLockContainer<NodeKey>(512);
+ LockContainer container = new ReentrantStripedLockContainer(512);
Map<Lock, Integer> distribution = new HashMap<Lock, Integer>();
for (Fqn f : fqns) {
NodeKey dataKey = new NodeKey(f, NodeKey.Type.DATA);
Modified: core/branches/flat/src/test/java/org/horizon/lock/LockContainerHashingTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/lock/LockContainerHashingTest.java 2009-03-18 14:56:14 UTC (rev 7913)
+++ core/branches/flat/src/test/java/org/horizon/lock/LockContainerHashingTest.java 2009-03-18 15:48:28 UTC (rev 7914)
@@ -21,8 +21,8 @@
*/
package org.horizon.lock;
-import org.horizon.util.concurrent.locks.LockContainer;
-import org.horizon.util.concurrent.locks.ReentrantLockContainer;
+import org.horizon.util.concurrent.locks.containers.AbstractStripedLockContainer;
+import org.horizon.util.concurrent.locks.containers.ReentrantStripedLockContainer;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -35,11 +35,11 @@
@Test(groups = "unit", testName = "lock.LockContainerHashingTest")
public class LockContainerHashingTest {
- private LockContainer<String> stripedLock;
+ private AbstractStripedLockContainer stripedLock;
@BeforeMethod(alwaysRun = true)
public void setUp() {
- stripedLock = new ReentrantLockContainer<String>(500);
+ stripedLock = new ReentrantStripedLockContainer(500);
}
public void testHashingDistribution() {
15 years, 9 months
JBoss Cache SVN: r7913 - core/branches/flat/src/test/java/org/horizon/loader/jdbc.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-03-18 10:56:14 -0400 (Wed, 18 Mar 2009)
New Revision: 7913
Modified:
core/branches/flat/src/test/java/org/horizon/loader/jdbc/PooledConnectionFactoryTest.java
Log:
Disabled hanging test
Modified: core/branches/flat/src/test/java/org/horizon/loader/jdbc/PooledConnectionFactoryTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/loader/jdbc/PooledConnectionFactoryTest.java 2009-03-18 14:53:15 UTC (rev 7912)
+++ core/branches/flat/src/test/java/org/horizon/loader/jdbc/PooledConnectionFactoryTest.java 2009-03-18 14:56:14 UTC (rev 7913)
@@ -14,7 +14,7 @@
*
* @author
*/
-@Test(groups = "functional", testName = "loader.jdbc.PooledConnectionFactoryTest")
+@Test(groups = "functional", testName = "loader.jdbc.PooledConnectionFactoryTest", enabled = false)
public class PooledConnectionFactoryTest {
private PooledConnectionFactory factory;
15 years, 9 months
JBoss Cache SVN: r7912 - core/branches/flat/src/test/java/org/horizon/test.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-03-18 10:53:15 -0400 (Wed, 18 Mar 2009)
New Revision: 7912
Modified:
core/branches/flat/src/test/java/org/horizon/test/MultipleCacheManagersTest.java
Log:
changes to abstract class
Modified: core/branches/flat/src/test/java/org/horizon/test/MultipleCacheManagersTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/test/MultipleCacheManagersTest.java 2009-03-18 14:45:39 UTC (rev 7911)
+++ core/branches/flat/src/test/java/org/horizon/test/MultipleCacheManagersTest.java 2009-03-18 14:53:15 UTC (rev 7912)
@@ -177,10 +177,8 @@
protected Configuration getDefaultClusteredConfig(Configuration.CacheMode mode) {
Configuration configuration = new Configuration();
configuration.setCacheMode(mode);
- if (mode.isSynchronous()) {
- configuration.setSyncCommitPhase(true);
- configuration.setSyncRollbackPhase(true);
- }
+ configuration.setSyncCommitPhase(true);
+ configuration.setSyncRollbackPhase(true);
configuration.setFetchInMemoryState(false);
return configuration;
}
15 years, 9 months
JBoss Cache SVN: r7911 - in core/branches/flat/src: main/java/org/horizon/factories and 2 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-03-18 10:45:39 -0400 (Wed, 18 Mar 2009)
New Revision: 7911
Added:
core/branches/flat/src/main/java/org/horizon/container/NullMarkerEntryForRemoval.java
Modified:
core/branches/flat/src/main/java/org/horizon/container/NullMarkerEntry.java
core/branches/flat/src/main/java/org/horizon/factories/EntryFactory.java
core/branches/flat/src/main/java/org/horizon/factories/EntryFactoryImpl.java
core/branches/flat/src/main/java/org/horizon/interceptors/CacheLoaderInterceptor.java
core/branches/flat/src/main/java/org/horizon/interceptors/LockingInterceptor.java
core/branches/flat/src/test/java/org/horizon/api/mvcc/repeatable_read/RepeatableReadLockTest.java
Log:
Fixed bug in repeatable read when removing a null entry
Modified: core/branches/flat/src/main/java/org/horizon/container/NullMarkerEntry.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/container/NullMarkerEntry.java 2009-03-18 14:02:03 UTC (rev 7910)
+++ core/branches/flat/src/main/java/org/horizon/container/NullMarkerEntry.java 2009-03-18 14:45:39 UTC (rev 7911)
@@ -28,31 +28,16 @@
* @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
* @since 1.0
*/
-public class NullMarkerEntry extends ReadCommittedEntry {
- /**
- * @return always returns true
- */
- @Override
- public boolean isNullEntry() {
- return true;
- }
+public class NullMarkerEntry extends NullMarkerEntryForRemoval {
- /**
- * @return always returns true so that any get commands, upon getting this entry, will ignore the entry as though it
- * were removed.
- */
- @Override
- public boolean isDeleted() {
- return true;
+ private static final NullMarkerEntry INSTANCE = new NullMarkerEntry();
+
+ private NullMarkerEntry() {
+ super(null);
}
- /**
- * @return always returns true so that any get commands, upon getting this entry, will ignore the entry as though it
- * were invalid.
- */
- @Override
- public boolean isValid() {
- return false;
+ public static NullMarkerEntry getInstance() {
+ return INSTANCE;
}
/**
Added: core/branches/flat/src/main/java/org/horizon/container/NullMarkerEntryForRemoval.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/container/NullMarkerEntryForRemoval.java (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/container/NullMarkerEntryForRemoval.java 2009-03-18 14:45:39 UTC (rev 7911)
@@ -0,0 +1,41 @@
+package org.horizon.container;
+
+/**
+ * A null entry that is read in for removal
+ *
+ * @author Manik Surtani
+ * @since 1.0
+ */
+public class NullMarkerEntryForRemoval extends RepeatableReadEntry {
+
+ public NullMarkerEntryForRemoval(Object key) {
+ super(key, null, -1);
+ }
+
+ /**
+ * @return always returns true
+ */
+ @Override
+ public boolean isNullEntry() {
+ return true;
+ }
+
+ /**
+ * @return always returns true so that any get commands, upon getting this entry, will ignore the entry as though it
+ * were removed.
+ */
+ @Override
+ public boolean isDeleted() {
+ return true;
+ }
+
+ /**
+ * @return always returns true so that any get commands, upon getting this entry, will ignore the entry as though it
+ * were invalid.
+ */
+ @Override
+ public boolean isValid() {
+ return false;
+ }
+
+}
Modified: core/branches/flat/src/main/java/org/horizon/factories/EntryFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/EntryFactory.java 2009-03-18 14:02:03 UTC (rev 7910)
+++ core/branches/flat/src/main/java/org/horizon/factories/EntryFactory.java 2009-03-18 14:45:39 UTC (rev 7911)
@@ -48,7 +48,7 @@
*/
boolean acquireLock(InvocationContext ctx, Object key) throws InterruptedException, TimeoutException;
- MVCCEntry wrapEntryForWriting(InvocationContext ctx, Object key, boolean createIfAbsent, boolean forceLockIfAbsent, boolean alreadyLocked) throws InterruptedException;
+ MVCCEntry wrapEntryForWriting(InvocationContext ctx, Object key, boolean createIfAbsent, boolean forceLockIfAbsent, boolean alreadyLocked, boolean forRemoval) throws InterruptedException;
MVCCEntry wrapEntryForReading(InvocationContext ctx, Object key) throws InterruptedException;
}
Modified: core/branches/flat/src/main/java/org/horizon/factories/EntryFactoryImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/EntryFactoryImpl.java 2009-03-18 14:02:03 UTC (rev 7910)
+++ core/branches/flat/src/main/java/org/horizon/factories/EntryFactoryImpl.java 2009-03-18 14:45:39 UTC (rev 7911)
@@ -26,6 +26,7 @@
import org.horizon.container.DataContainer;
import org.horizon.container.MVCCEntry;
import org.horizon.container.NullMarkerEntry;
+import org.horizon.container.NullMarkerEntryForRemoval;
import org.horizon.container.ReadCommittedEntry;
import org.horizon.container.RepeatableReadEntry;
import org.horizon.container.UpdateableEntry;
@@ -42,7 +43,6 @@
public class EntryFactoryImpl implements EntryFactory {
private boolean useRepeatableRead;
- private static final NullMarkerEntry NULL_MARKER = new NullMarkerEntry();
DataContainer container;
boolean writeSkewCheck;
LockManager lockManager;
@@ -66,8 +66,10 @@
writeSkewCheck = configuration.isWriteSkewCheck();
}
- public final UpdateableEntry createWrappedEntry(Object key, Object value, boolean isForInsert, long lifespan) {
- if (value == null && !isForInsert) return useRepeatableRead ? NULL_MARKER : null;
+ private UpdateableEntry createWrappedEntry(Object key, Object value, boolean isForInsert, boolean forRemoval, long lifespan) {
+ if (value == null && !isForInsert) return useRepeatableRead ?
+ forRemoval ? new NullMarkerEntryForRemoval(key) : NullMarkerEntry.getInstance()
+ : null;
return useRepeatableRead ? new RepeatableReadEntry(key, value, lifespan) : new ReadCommittedEntry(key, value, lifespan);
}
@@ -76,7 +78,7 @@
MVCCEntry mvccEntry;
if (ctx.hasOption(Options.FORCE_WRITE_LOCK)) {
if (trace) log.trace("Forcing lock on reading");
- return wrapEntryForWriting(ctx, key, false, false, false);
+ return wrapEntryForWriting(ctx, key, false, false, false, false);
} else if ((mvccEntry = ctx.lookupEntry(key)) == null) {
if (trace) log.trace("Key " + key + " is not in context, fetching from container.");
// simple implementation. Peek the entry, wrap it, put wrapped entry in the context.
@@ -88,8 +90,8 @@
if (se != null) ctx.putLookedUpEntry(key, se);
} else {
mvccEntry = se == null ?
- createWrappedEntry(key, null, false, -1) :
- createWrappedEntry(key, se.getValue(), false, se.getLifespan());
+ createWrappedEntry(key, null, false, false, -1) :
+ createWrappedEntry(key, se.getValue(), false, false, se.getLifespan());
if (mvccEntry != null) ctx.putLookedUpEntry(key, mvccEntry);
}
@@ -100,7 +102,7 @@
}
}
- public final MVCCEntry wrapEntryForWriting(InvocationContext ctx, Object key, boolean createIfAbsent, boolean forceLockIfAbsent, boolean alreadyLocked) throws InterruptedException {
+ public final MVCCEntry wrapEntryForWriting(InvocationContext ctx, Object key, boolean createIfAbsent, boolean forceLockIfAbsent, boolean alreadyLocked, boolean forRemoval) throws InterruptedException {
MVCCEntry mvccEntry = ctx.lookupEntry(key);
if (createIfAbsent && mvccEntry != null && mvccEntry.isNullEntry()) mvccEntry = null;
if (mvccEntry != null) // exists in context! Just acquire lock if needed, and wrap.
@@ -108,11 +110,12 @@
// acquire lock if needed
if (alreadyLocked || acquireLock(ctx, key)) {
UpdateableEntry ue;
- if (mvccEntry instanceof UpdateableEntry) {
+
+ if (mvccEntry instanceof UpdateableEntry && (!forRemoval || !(mvccEntry instanceof NullMarkerEntry))) {
ue = (UpdateableEntry) mvccEntry;
} else {
// this is a read-only entry that needs to be copied to a proper read-write entry!!
- ue = createWrappedEntry(key, mvccEntry.getValue(), false, mvccEntry.getLifespan());
+ ue = createWrappedEntry(key, mvccEntry.getValue(), false, forRemoval, mvccEntry.getLifespan());
mvccEntry = ue;
ctx.putLookedUpEntry(key, mvccEntry);
}
@@ -134,7 +137,7 @@
// exists in cache! Just acquire lock if needed, and wrap.
// do we need a lock?
boolean needToCopy = alreadyLocked || acquireLock(ctx, key) || ctx.hasOption(Options.SKIP_LOCKING); // even if we do not acquire a lock, if skip-locking is enabled we should copy
- UpdateableEntry ue = createWrappedEntry(key, cachedValue.getValue(), false, cachedValue.getLifespan());
+ UpdateableEntry ue = createWrappedEntry(key, cachedValue.getValue(), false, false, cachedValue.getLifespan());
ctx.putLookedUpEntry(key, ue);
if (needToCopy) ue.copyForUpdate(container, writeSkewCheck);
mvccEntry = ue;
@@ -144,7 +147,7 @@
// now to lock and create the entry. Lock first to prevent concurrent creation!
if (!alreadyLocked) acquireLock(ctx, key);
notifier.notifyCacheEntryCreated(key, true, ctx);
- UpdateableEntry ue = createWrappedEntry(key, null, true, -1);
+ UpdateableEntry ue = createWrappedEntry(key, null, true, false, -1);
ue.setCreated(true);
ctx.putLookedUpEntry(key, ue);
ue.copyForUpdate(container, writeSkewCheck);
Modified: core/branches/flat/src/main/java/org/horizon/interceptors/CacheLoaderInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/CacheLoaderInterceptor.java 2009-03-18 14:02:03 UTC (rev 7910)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/CacheLoaderInterceptor.java 2009-03-18 14:45:39 UTC (rev 7911)
@@ -126,7 +126,7 @@
}
// Reuse the lock and create a new entry for loading
- MVCCEntry n = entryFactory.wrapEntryForWriting(ctx, key, true, false, keyLocked);
+ MVCCEntry n = entryFactory.wrapEntryForWriting(ctx, key, true, false, keyLocked, false);
n = loadEntry(ctx, key, n);
ctx.setContainsModifications(true);
}
Modified: core/branches/flat/src/main/java/org/horizon/interceptors/LockingInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/LockingInterceptor.java 2009-03-18 14:02:03 UTC (rev 7910)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/LockingInterceptor.java 2009-03-18 14:45:39 UTC (rev 7911)
@@ -129,7 +129,8 @@
public Object visitClearCommand(InvocationContext ctx, ClearCommand command) throws Throwable {
try {
// get a snapshot of all keys in the data container
- for (Object key : dataContainer.keySet()) entryFactory.wrapEntryForWriting(ctx, key, false, false, false);
+ for (Object key : dataContainer.keySet())
+ entryFactory.wrapEntryForWriting(ctx, key, false, false, false, false);
ctx.setContainsModifications(true);
return invokeNextInterceptor(ctx, command);
} finally {
@@ -147,7 +148,7 @@
public Object visitInvalidateCommand(InvocationContext ctx, InvalidateCommand command) throws Throwable {
try {
if (command.getKeys() != null) {
- for (Object key : command.getKeys()) entryFactory.wrapEntryForWriting(ctx, key, false, true, false);
+ for (Object key : command.getKeys()) entryFactory.wrapEntryForWriting(ctx, key, false, true, false, false);
}
Object o = invokeNextInterceptor(ctx, command);
if (!ctx.isContainsModifications()) ctx.setContainsModifications(command.isSuccessful());
@@ -160,7 +161,7 @@
@Override
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
try {
- entryFactory.wrapEntryForWriting(ctx, command.getKey(), true, false, false);
+ entryFactory.wrapEntryForWriting(ctx, command.getKey(), true, false, false, false);
Object o = invokeNextInterceptor(ctx, command);
if (!ctx.isContainsModifications()) ctx.setContainsModifications(command.isSuccessful());
return o;
@@ -173,7 +174,7 @@
public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable {
try {
for (Object key : command.getMap().keySet()) {
- entryFactory.wrapEntryForWriting(ctx, key, true, false, false);
+ entryFactory.wrapEntryForWriting(ctx, key, true, false, false, false);
}
Object o = invokeNextInterceptor(ctx, command);
if (!ctx.isContainsModifications()) ctx.setContainsModifications(command.isSuccessful());
@@ -187,7 +188,7 @@
@Override
public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
try {
- entryFactory.wrapEntryForWriting(ctx, command.getKey(), false, true, false);
+ entryFactory.wrapEntryForWriting(ctx, command.getKey(), false, true, false, true);
Object o = invokeNextInterceptor(ctx, command);
if (!ctx.isContainsModifications()) ctx.setContainsModifications(command.isSuccessful());
return o;
@@ -200,7 +201,7 @@
@Override
public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
try {
- entryFactory.wrapEntryForWriting(ctx, command.getKey(), false, true, false);
+ entryFactory.wrapEntryForWriting(ctx, command.getKey(), false, true, false, false);
Object o = invokeNextInterceptor(ctx, command);
if (!ctx.isContainsModifications()) ctx.setContainsModifications(command.isSuccessful());
return o;
Modified: core/branches/flat/src/test/java/org/horizon/api/mvcc/repeatable_read/RepeatableReadLockTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/mvcc/repeatable_read/RepeatableReadLockTest.java 2009-03-18 14:02:03 UTC (rev 7910)
+++ core/branches/flat/src/test/java/org/horizon/api/mvcc/repeatable_read/RepeatableReadLockTest.java 2009-03-18 14:45:39 UTC (rev 7911)
@@ -95,4 +95,21 @@
assert "v".equals(cache.get("k"));
assertNoLocks();
}
+
+ public void testRepeatableReadWithNullRemoval() throws Exception {
+ LockTestBaseTL tl = threadLocal.get();
+ Cache<String, String> cache = tl.cache;
+ TransactionManager tm = tl.tm;
+
+ // start with an empty cache
+ tm.begin();
+ cache.get("a");
+ Transaction tx = tm.suspend();
+ cache.put("a", "v2");
+ assert cache.get("a").equals("v2");
+ tm.resume(tx);
+ cache.remove("a");
+ tx.commit();
+ assert cache.get("a") == null;
+ }
}
15 years, 9 months
JBoss Cache SVN: r7910 - in core/branches/flat/src/test/java/org/horizon: api/mvcc and 9 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-03-18 10:02:03 -0400 (Wed, 18 Mar 2009)
New Revision: 7910
Added:
core/branches/flat/src/test/java/org/horizon/tx/TransactionsSpanningCaches.java
core/branches/flat/src/test/java/org/horizon/tx/TransactionsSpanningReplicatedCaches.java
Modified:
core/branches/flat/src/test/java/org/horizon/api/MixedModeTest.java
core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java
core/branches/flat/src/test/java/org/horizon/api/tree/NodeReplicatedMoveTest.java
core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTest.java
core/branches/flat/src/test/java/org/horizon/atomic/ClusteredAPITest.java
core/branches/flat/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java
core/branches/flat/src/test/java/org/horizon/invalidation/BaseInvalidationTest.java
core/branches/flat/src/test/java/org/horizon/loader/decorators/SingletonStoreTest.java
core/branches/flat/src/test/java/org/horizon/marshall/MarshalledValueTest.java
core/branches/flat/src/test/java/org/horizon/replication/AsyncReplTest.java
core/branches/flat/src/test/java/org/horizon/replication/BaseReplicatedAPITest.java
core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java
core/branches/flat/src/test/java/org/horizon/replication/ReplicationQueueTest.java
core/branches/flat/src/test/java/org/horizon/replication/SyncCacheListenerTest.java
core/branches/flat/src/test/java/org/horizon/replication/SyncReplTest.java
core/branches/flat/src/test/java/org/horizon/test/MultipleCacheManagersTest.java
Log:
Added test to ensure transactions span caches on the same manager
Modified: core/branches/flat/src/test/java/org/horizon/api/MixedModeTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/MixedModeTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/api/MixedModeTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -15,21 +15,12 @@
AdvancedCache localCache1, localCache2;
protected void createCacheManagers() throws Throwable {
- Configuration replSync = getDefaultConfig();
- replSync.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ Configuration replSync = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
+ Configuration replAsync = getDefaultClusteredConfig(Configuration.CacheMode.REPL_ASYNC);
+ Configuration invalSync = getDefaultClusteredConfig(Configuration.CacheMode.INVALIDATION_SYNC);
+ Configuration invalAsync = getDefaultClusteredConfig(Configuration.CacheMode.INVALIDATION_ASYNC);
+ Configuration local = getDefaultClusteredConfig(Configuration.CacheMode.LOCAL);
- Configuration replAsync = getDefaultConfig();
- replAsync.setCacheMode(Configuration.CacheMode.REPL_ASYNC);
-
- Configuration invalSync = getDefaultConfig();
- invalSync.setCacheMode(Configuration.CacheMode.INVALIDATION_SYNC);
-
- Configuration invalAsync = getDefaultConfig();
- invalAsync.setCacheMode(Configuration.CacheMode.INVALIDATION_ASYNC);
-
- Configuration local = getDefaultConfig();
- local.setCacheMode(Configuration.CacheMode.LOCAL);
-
createClusteredCaches(2, "replSync", replSync);
defineCacheOnAllManagers("replAsync", replAsync);
defineCacheOnAllManagers("invalSync", invalSync);
Modified: core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -35,8 +35,7 @@
ReplListener replListener1, replListener2;
protected void createCacheManagers() throws Throwable {
- Configuration c = getDefaultConfig();
- c.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ Configuration c = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
createClusteredCaches(2, "replSync", c);
Modified: core/branches/flat/src/test/java/org/horizon/api/tree/NodeReplicatedMoveTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/tree/NodeReplicatedMoveTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/api/tree/NodeReplicatedMoveTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -31,9 +31,8 @@
TransactionManager tm1;
protected void createCacheManagers() throws Throwable {
- Configuration c = getDefaultConfig();
+ Configuration c = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
c.setInvocationBatchingEnabled(true);
- c.setCacheMode(Configuration.CacheMode.REPL_SYNC);
c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
createClusteredCaches(2, "replSync", c);
Modified: core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -29,10 +29,8 @@
private TreeCache<Object, Object> cache1, cache2;
protected void createCacheManagers() throws Throwable {
- Configuration c = getDefaultConfig();
- c.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ Configuration c = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
c.setInvocationBatchingEnabled(true);
- c.setFetchInMemoryState(false);
createClusteredCaches(2, "replSync", c);
Modified: core/branches/flat/src/test/java/org/horizon/atomic/ClusteredAPITest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/atomic/ClusteredAPITest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/atomic/ClusteredAPITest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -17,9 +17,8 @@
AtomicMapCache cache1, cache2;
protected void createCacheManagers() throws Throwable {
- Configuration c = getDefaultConfig();
+ Configuration c = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
- c.setCacheMode(Configuration.CacheMode.REPL_SYNC);
c.setInvocationBatchingEnabled(true);
List<Cache> caches = createClusteredCaches(2, "atomic", c);
Modified: core/branches/flat/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -14,8 +14,7 @@
Cache c1, c2;
protected void createCacheManagers() throws Throwable {
- Configuration cfg = getDefaultConfig();
- cfg.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ Configuration cfg = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
List<Cache> caches = createClusteredCaches(2, "cache", cfg);
c1 = caches.get(0);
c2 = caches.get(1);
Modified: core/branches/flat/src/test/java/org/horizon/invalidation/BaseInvalidationTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/invalidation/BaseInvalidationTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/invalidation/BaseInvalidationTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -32,10 +32,8 @@
protected boolean isSync;
protected void createCacheManagers() throws Throwable {
- Configuration c = getDefaultConfig();
+ Configuration c = getDefaultClusteredConfig(isSync ? Configuration.CacheMode.INVALIDATION_SYNC : Configuration.CacheMode.INVALIDATION_ASYNC);
c.setStateRetrievalTimeout(1000);
- c.setFetchInMemoryState(false);
- c.setCacheMode(isSync ? Configuration.CacheMode.INVALIDATION_SYNC : Configuration.CacheMode.INVALIDATION_ASYNC);
c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
List<Cache> caches = createClusteredCaches(2, "invalidation", c);
cache1 = caches.get(0).getAdvancedCache();
Modified: core/branches/flat/src/test/java/org/horizon/loader/decorators/SingletonStoreTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/loader/decorators/SingletonStoreTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/loader/decorators/SingletonStoreTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -45,8 +45,7 @@
cm1 = addClusterEnabledCacheManager();
cm2 = addClusterEnabledCacheManager();
- Configuration conf = getDefaultConfig();
- conf.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ Configuration conf = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
DummyInMemoryCacheStore.Cfg cfg = new DummyInMemoryCacheStore.Cfg();
cfg.setStore("Store-" + storeCounter.getAndIncrement());
CacheLoaderManagerConfig pushingCfg = new CacheLoaderManagerConfig();
@@ -64,8 +63,7 @@
((DummyInMemoryCacheStore.Cfg) conf.getCacheLoaderManagerConfig().getFirstCacheLoaderConfig()).setStore("Store-" + storeCounter.getAndIncrement());
cm2.defineCache("pushing", conf);
- conf = getDefaultConfig();
- conf.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ conf = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
cfg = new DummyInMemoryCacheStore.Cfg();
cfg.setStore("Store-" + storeCounter.getAndIncrement());
CacheLoaderManagerConfig nonPushingCfg = new CacheLoaderManagerConfig();
Modified: core/branches/flat/src/test/java/org/horizon/marshall/MarshalledValueTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/marshall/MarshalledValueTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/marshall/MarshalledValueTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -46,8 +46,7 @@
String k = "key", v = "value";
protected void createCacheManagers() throws Throwable {
- Configuration replSync = getDefaultConfig();
- replSync.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ Configuration replSync = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
replSync.setUseLazyDeserialization(true);
createClusteredCaches(2, "replSync", replSync);
@@ -249,8 +248,7 @@
public void testCacheLoaders() throws CloneNotSupportedException {
tearDown();
- Configuration cacheCofig = getDefaultConfig();
- cacheCofig.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ Configuration cacheCofig = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
cacheCofig.setUseLazyDeserialization(true);
CacheLoaderManagerConfig clmc = new CacheLoaderManagerConfig();
DummyInMemoryCacheStore.Cfg clc = new DummyInMemoryCacheStore.Cfg();
Modified: core/branches/flat/src/test/java/org/horizon/replication/AsyncReplTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/AsyncReplTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/replication/AsyncReplTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -26,10 +26,7 @@
Cache cache1, cache2;
protected void createCacheManagers() throws Throwable {
- Configuration asyncConfiguration = getDefaultConfig();
- asyncConfiguration.setCacheMode(Configuration.CacheMode.REPL_ASYNC);
- asyncConfiguration.setSyncCommitPhase(true);
- asyncConfiguration.setSyncRollbackPhase(true);
+ Configuration asyncConfiguration = getDefaultClusteredConfig(Configuration.CacheMode.REPL_ASYNC);
asyncConfiguration.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
List<Cache> caches = createClusteredCaches(2, "asyncRepl", asyncConfiguration);
cache1 = caches.get(0);
Modified: core/branches/flat/src/test/java/org/horizon/replication/BaseReplicatedAPITest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/BaseReplicatedAPITest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/replication/BaseReplicatedAPITest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -22,10 +22,8 @@
protected boolean isSync;
protected void createCacheManagers() throws Throwable {
- Configuration c = getDefaultConfig();
+ Configuration c = getDefaultClusteredConfig(isSync ? Configuration.CacheMode.REPL_SYNC : Configuration.CacheMode.REPL_ASYNC);
c.setStateRetrievalTimeout(1000);
- c.setFetchInMemoryState(false);
- c.setCacheMode(isSync ? Configuration.CacheMode.REPL_SYNC : Configuration.CacheMode.REPL_ASYNC);
c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
List<Cache> caches = createClusteredCaches(2, "replication", c);
cache1 = caches.get(0).getAdvancedCache();
Modified: core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -35,9 +35,7 @@
private AdvancedCache cache1, cache2;
protected void createCacheManagers() throws Throwable {
- Configuration configuration = getDefaultConfig();
-
- configuration.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ Configuration configuration = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
configuration.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
configuration.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
Modified: core/branches/flat/src/test/java/org/horizon/replication/ReplicationQueueTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/ReplicationQueueTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/replication/ReplicationQueueTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -13,11 +13,11 @@
import javax.transaction.TransactionManager;
import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.CountDownLatch;
/**
* Tests RepliationQueue functionality.
@@ -41,9 +41,8 @@
CacheManager second = TestingUtil.createClusteredCacheManager(globalConfiguration);
registerCacheManager(first, second);
- Configuration config = getDefaultConfig();
+ Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.REPL_ASYNC);
config.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
- config.setCacheMode(Configuration.CacheMode.REPL_ASYNC);
config.setUseReplQueue(true);
config.setReplQueueInterval(REPL_QUEUE_INTERVAL);
config.setReplQueueMaxElements(REPL_QUEUE_MAX_ELEMENTS);
Modified: core/branches/flat/src/test/java/org/horizon/replication/SyncCacheListenerTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/SyncCacheListenerTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/replication/SyncCacheListenerTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -38,9 +38,7 @@
private final static Log log = LogFactory.getLog(SyncCacheListenerTest.class);
protected void createCacheManagers() throws Throwable {
- Configuration conf = getDefaultConfig();
- conf.setSyncCommitPhase(true);
- conf.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ Configuration conf = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
conf.setIsolationLevel(IsolationLevel.SERIALIZABLE);
conf.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
conf.setLockAcquisitionTimeout(5000);
Modified: core/branches/flat/src/test/java/org/horizon/replication/SyncReplTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/SyncReplTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/replication/SyncReplTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -35,8 +35,7 @@
String k = "key", v = "value";
protected void createCacheManagers() throws Throwable {
- Configuration replSync = getDefaultConfig();
- replSync.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ Configuration replSync = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
createClusteredCaches(2, "replSync", replSync);
cache1 = manager(0).getCache("replSync");
@@ -64,8 +63,7 @@
assert cache1.isEmpty();
assert cache2.isEmpty();
- Configuration newConf = getDefaultConfig();
- newConf.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ Configuration newConf = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
defineCacheOnAllManagers("newCache", newConf);
Cache altCache1 = manager(0).getCache("newCache");
Cache altCache2 = manager(1).getCache("newCache");
@@ -95,8 +93,7 @@
assert cache1.isEmpty();
assert cache2.isEmpty();
- Configuration newConf = getDefaultConfig();
- newConf.setCacheMode(Configuration.CacheMode.REPL_SYNC);
+ Configuration newConf = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
defineCacheOnAllManagers("newCache2", newConf);
Cache altCache1 = manager(0).getCache("newCache2");
@@ -123,8 +120,7 @@
Transport originalTransport = null;
RPCManagerImpl rpcManager = null;
try {
- Configuration asyncCache = getDefaultConfig();
- asyncCache.setCacheMode(Configuration.CacheMode.REPL_ASYNC);
+ Configuration asyncCache = getDefaultClusteredConfig(Configuration.CacheMode.REPL_ASYNC);
defineCacheOnAllManagers("asyncCache", asyncCache);
Cache asyncCache1 = manager(0).getCache("asyncCache");
Modified: core/branches/flat/src/test/java/org/horizon/test/MultipleCacheManagersTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/test/MultipleCacheManagersTest.java 2009-03-18 11:36:28 UTC (rev 7909)
+++ core/branches/flat/src/test/java/org/horizon/test/MultipleCacheManagersTest.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -90,7 +90,7 @@
}
/**
- * @see #getDefaultConfig()
+ * @see #getDefaultReplicatedConfig()
*/
private void assertSupportedConfig() {
for (CacheManager cm : cacheManagers) {
@@ -174,10 +174,13 @@
* make sure that an commit message will be dispatched in the same test method it was triggered and it will not
* interfere with further log messages.
*/
- protected Configuration getDefaultConfig() {
+ protected Configuration getDefaultClusteredConfig(Configuration.CacheMode mode) {
Configuration configuration = new Configuration();
- configuration.setSyncCommitPhase(true);
- configuration.setSyncRollbackPhase(true);
+ configuration.setCacheMode(mode);
+ if (mode.isSynchronous()) {
+ configuration.setSyncCommitPhase(true);
+ configuration.setSyncRollbackPhase(true);
+ }
configuration.setFetchInMemoryState(false);
return configuration;
}
Added: core/branches/flat/src/test/java/org/horizon/tx/TransactionsSpanningCaches.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/tx/TransactionsSpanningCaches.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/tx/TransactionsSpanningCaches.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -0,0 +1,104 @@
+package org.horizon.tx;
+
+import org.horizon.Cache;
+import org.horizon.config.Configuration;
+import org.horizon.manager.CacheManager;
+import org.horizon.manager.DefaultCacheManager;
+import org.horizon.test.SingleCacheManagerTest;
+import org.horizon.test.TestingUtil;
+import org.horizon.transaction.DummyTransactionManagerLookup;
+import org.testng.annotations.Test;
+
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+@Test(groups = "functional", sequential = true, testName = "tx.TransactionsSpanningCaches")
+public class TransactionsSpanningCaches extends SingleCacheManagerTest {
+
+ protected CacheManager createCacheManager() throws Exception {
+ Configuration c = new Configuration();
+ c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+ CacheManager cm = new DefaultCacheManager(c);
+ cm.defineCache("c1", c);
+ cm.defineCache("c2", c);
+ return cm;
+ }
+
+ public void testCommitSpanningCaches() throws Exception {
+ Cache c1 = cacheManager.getCache("c1");
+ Cache c2 = cacheManager.getCache("c2");
+
+ assert c1.isEmpty();
+ assert c2.isEmpty();
+
+ c1.put("c1key", "c1value");
+ c2.put("c2key", "c2value");
+
+ assert !c1.isEmpty();
+ assert c1.size() == 1;
+ assert c1.get("c1key").equals("c1value");
+
+ assert !c2.isEmpty();
+ assert c2.size() == 1;
+ assert c2.get("c2key").equals("c2value");
+
+ TransactionManager tm = TestingUtil.getTransactionManager(c1);
+
+ tm.begin();
+ c1.put("c1key", "c1value_new");
+ c2.put("c2key", "c2value_new");
+
+ assert c1.get("c1key").equals("c1value_new");
+ assert c2.get("c2key").equals("c2value_new");
+
+ Transaction tx = tm.suspend();
+
+ assert c1.get("c1key").equals("c1value");
+ assert c2.get("c2key").equals("c2value");
+
+ tm.resume(tx);
+ tm.commit();
+
+ assert c1.get("c1key").equals("c1value_new");
+ assert c2.get("c2key").equals("c2value_new");
+ }
+
+ public void testRollbackSpanningCaches() throws Exception {
+ Cache c1 = cacheManager.getCache("c1");
+ Cache c2 = cacheManager.getCache("c2");
+
+ assert c1.isEmpty();
+ assert c2.isEmpty();
+
+ c1.put("c1key", "c1value");
+ c2.put("c2key", "c2value");
+
+ assert !c1.isEmpty();
+ assert c1.size() == 1;
+ assert c1.get("c1key").equals("c1value");
+
+ assert !c2.isEmpty();
+ assert c2.size() == 1;
+ assert c2.get("c2key").equals("c2value");
+
+ TransactionManager tm = TestingUtil.getTransactionManager(c1);
+
+ tm.begin();
+ c1.put("c1key", "c1value_new");
+ c2.put("c2key", "c2value_new");
+
+ assert c1.get("c1key").equals("c1value_new");
+ assert c2.get("c2key").equals("c2value_new");
+
+ Transaction tx = tm.suspend();
+
+ assert c1.get("c1key").equals("c1value");
+ assert c2.get("c2key").equals("c2value");
+
+ tm.resume(tx);
+ tm.rollback();
+
+ assert c1.get("c1key").equals("c1value");
+ assert c2.get("c2key").equals("c2value");
+ }
+}
Added: core/branches/flat/src/test/java/org/horizon/tx/TransactionsSpanningReplicatedCaches.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/tx/TransactionsSpanningReplicatedCaches.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/tx/TransactionsSpanningReplicatedCaches.java 2009-03-18 14:02:03 UTC (rev 7910)
@@ -0,0 +1,140 @@
+package org.horizon.tx;
+
+import org.horizon.Cache;
+import org.horizon.config.Configuration;
+import org.horizon.manager.CacheManager;
+import org.horizon.test.MultipleCacheManagersTest;
+import org.horizon.test.TestingUtil;
+import org.horizon.transaction.DummyTransactionManagerLookup;
+import org.testng.annotations.Test;
+
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.util.Arrays;
+
+@Test(groups = "functional", sequential = true, testName = "tx.TransactionsSpanningReplicatedCaches")
+public class TransactionsSpanningReplicatedCaches extends MultipleCacheManagersTest {
+
+ CacheManager cm1, cm2;
+
+ public TransactionsSpanningReplicatedCaches() {
+ cleanup = CleanupPhase.AFTER_METHOD;
+ }
+
+ protected void createCacheManagers() throws Exception {
+ cm1 = addClusterEnabledCacheManager();
+ cm2 = addClusterEnabledCacheManager();
+
+ Configuration c = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
+ c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+
+ defineCacheOnAllManagers("c1", c);
+ defineCacheOnAllManagers("c2", c);
+ }
+
+ public void testCommitSpanningCaches() throws Exception {
+ Cache c1 = cm1.getCache("c1");
+ Cache c1Replica = cm2.getCache("c1");
+ Cache c2 = cm1.getCache("c2");
+ Cache c2Replica = cm2.getCache("c2");
+
+ assert c1.isEmpty();
+ assert c2.isEmpty();
+ assert c1Replica.isEmpty();
+ assert c2Replica.isEmpty();
+
+ c1.put("c1key", "c1value");
+ c2.put("c2key", "c2value");
+
+ for (Cache c : Arrays.asList(c1, c1Replica)) {
+ assert !c.isEmpty();
+ assert c.size() == 1;
+ assert c.get("c1key").equals("c1value");
+ }
+
+ for (Cache c : Arrays.asList(c2, c2Replica)) {
+ assert !c.isEmpty();
+ assert c.size() == 1;
+ assert c.get("c2key").equals("c2value");
+ }
+
+ TransactionManager tm = TestingUtil.getTransactionManager(c1);
+
+ tm.begin();
+ c1.put("c1key", "c1value_new");
+ c2.put("c2key", "c2value_new");
+
+ assert c1.get("c1key").equals("c1value_new");
+ assert c1Replica.get("c1key").equals("c1value");
+ assert c2.get("c2key").equals("c2value_new");
+ assert c2Replica.get("c2key").equals("c2value");
+
+ Transaction tx = tm.suspend();
+
+ assert c1.get("c1key").equals("c1value");
+ assert c1Replica.get("c1key").equals("c1value");
+ assert c2.get("c2key").equals("c2value");
+ assert c2Replica.get("c2key").equals("c2value");
+
+ tm.resume(tx);
+ tm.commit();
+
+ assert c1.get("c1key").equals("c1value_new");
+ assert c1Replica.get("c1key").equals("c1value_new");
+ assert c2.get("c2key").equals("c2value_new");
+ assert c2Replica.get("c2key").equals("c2value_new");
+ }
+
+ public void testRollbackSpanningCaches() throws Exception {
+ Cache c1 = cm1.getCache("c1");
+ Cache c1Replica = cm2.getCache("c1");
+ Cache c2 = cm1.getCache("c2");
+ Cache c2Replica = cm2.getCache("c2");
+
+ assert c1.isEmpty();
+ assert c2.isEmpty();
+ assert c1Replica.isEmpty();
+ assert c2Replica.isEmpty();
+
+ c1.put("c1key", "c1value");
+ c2.put("c2key", "c2value");
+
+ for (Cache c : Arrays.asList(c1, c1Replica)) {
+ assert !c.isEmpty();
+ assert c.size() == 1;
+ assert c.get("c1key").equals("c1value");
+ }
+
+ for (Cache c : Arrays.asList(c2, c2Replica)) {
+ assert !c.isEmpty();
+ assert c.size() == 1;
+ assert c.get("c2key").equals("c2value");
+ }
+
+ TransactionManager tm = TestingUtil.getTransactionManager(c1);
+
+ tm.begin();
+ c1.put("c1key", "c1value_new");
+ c2.put("c2key", "c2value_new");
+
+ assert c1.get("c1key").equals("c1value_new");
+ assert c1Replica.get("c1key").equals("c1value");
+ assert c2.get("c2key").equals("c2value_new");
+ assert c2Replica.get("c2key").equals("c2value");
+
+ Transaction tx = tm.suspend();
+
+ assert c1.get("c1key").equals("c1value");
+ assert c1Replica.get("c1key").equals("c1value");
+ assert c2.get("c2key").equals("c2value");
+ assert c2Replica.get("c2key").equals("c2value");
+
+ tm.resume(tx);
+ tm.rollback();
+
+ assert c1.get("c1key").equals("c1value");
+ assert c1Replica.get("c1key").equals("c1value");
+ assert c2.get("c2key").equals("c2value");
+ assert c2Replica.get("c2key").equals("c2value");
+ }
+}
\ No newline at end of file
15 years, 9 months