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@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@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@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@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@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@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@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@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() {