[jbosscache-commits] JBoss Cache SVN: r7914 - in core/branches/flat/src: main/java/org/horizon/config/parsing and 8 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Wed Mar 18 11:48:29 EDT 2009


Author: manik.surtani at 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 at jboss.org">manik at 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 at jboss.org">manik at 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 at jboss.org">manik at jboss.org</a>)
- * @since 1.0
- */
- at 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 at jboss.org">manik at jboss.org</a>)
- * @see org.horizon.util.concurrent.locks.ReentrantLockContainer
- * @see org.horizon.util.concurrent.locks.OwnableReentrantLock
- * @since 1.0
- */
- at 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 at jboss.org">manik at jboss.org</a>)
- * @see org.horizon.util.concurrent.locks.OwnableReentrantLockContainer
- * @since 1.0
- */
- at 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 at jboss.org">manik at jboss.org</a>)
+ * @since 1.0
+ */
+ at 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 at jboss.org">manik at jboss.org</a>)
+ * @see ReentrantStripedLockContainer
+ * @see org.horizon.util.concurrent.locks.OwnableReentrantLock
+ * @since 1.0
+ */
+ at 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 at jboss.org">manik at jboss.org</a>)
+ * @see OwnableReentrantStripedLockContainer
+ * @since 1.0
+ */
+ at 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;
+
+ at 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
  */
- at Test (groups =  "unit" , testName = "api.tree.TreeStructureHashCodeTest")
+ at 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() {




More information about the jbosscache-commits mailing list