[jbosscache-commits] JBoss Cache SVN: r6442 - in core/trunk/src: main/java/org/jboss/cache/util/concurrent/locks and 2 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Wed Jul 30 11:43:05 EDT 2008


Author: manik.surtani at jboss.com
Date: 2008-07-30 11:43:05 -0400 (Wed, 30 Jul 2008)
New Revision: 6442

Added:
   core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/LockContainer.java
   core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/OwnableReentrantLockContainer.java
   core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/ReentrantLockContainer.java
Modified:
   core/trunk/src/main/java/org/jboss/cache/lock/MVCCLockManager.java
   core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/OwnableReentrantLock.java
   core/trunk/src/test/java/org/jboss/cache/api/mvcc/LockAssert.java
   core/trunk/src/test/java/org/jboss/cache/lock/MVCCLockManagerRecordingTest.java
Log:
Exracted LockContainer to separate class for better reuse

Modified: core/trunk/src/main/java/org/jboss/cache/lock/MVCCLockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/MVCCLockManager.java	2008-07-30 15:42:20 UTC (rev 6441)
+++ core/trunk/src/main/java/org/jboss/cache/lock/MVCCLockManager.java	2008-07-30 15:43:05 UTC (rev 6442)
@@ -1,6 +1,5 @@
 package org.jboss.cache.lock;
 
-import net.jcip.annotations.ThreadSafe;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.CacheSPI;
@@ -14,10 +13,12 @@
 import org.jboss.cache.invocation.InvocationContext;
 import org.jboss.cache.invocation.InvocationContextContainer;
 import static org.jboss.cache.lock.LockType.READ;
+import org.jboss.cache.util.concurrent.locks.LockContainer;
 import org.jboss.cache.util.concurrent.locks.OwnableReentrantLock;
+import org.jboss.cache.util.concurrent.locks.OwnableReentrantLockContainer;
+import org.jboss.cache.util.concurrent.locks.ReentrantLockContainer;
 
 import javax.transaction.TransactionManager;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -26,7 +27,6 @@
 import java.util.Set;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
 
 /**
  * This lock manager acquires and releases locks based on the Fqn passed in and not on the node itself.  The main benefit
@@ -48,7 +48,7 @@
  */
 public class MVCCLockManager extends FqnLockManager
 {
-   LockContainer lockContainer;
+   LockContainer<Fqn> lockContainer;
    DataContainer dataContainer;
    private Set<Fqn> internalFqns;
    private CacheSPI<?, ?> cache;
@@ -69,7 +69,7 @@
    @Start
    public void startLockManager()
    {
-      lockContainer = transactionManager == null ? new ReentrantLockContainer() : new OwnableReentrantLockContainer();
+      lockContainer = transactionManager == null ? new ReentrantLockContainer<Fqn>(configuration.getConcurrencyLevel()) : new OwnableReentrantLockContainer<Fqn>(configuration.getConcurrencyLevel(), invocationContextContainer);
    }
 
    @Start
@@ -281,150 +281,4 @@
    {
       return lockContainer.toString();
    }
-
-   @ThreadSafe
-   public abstract class LockContainer
-   {
-      private final int lockSegmentMask;
-      private final int lockSegmentShift;
-
-      /**
-       * Creates a new LockContainer which uses a certain number of shared locks across all elements that need to be locked.
-       */
-      LockContainer()
-      {
-         int tempLockSegShift = 0;
-         int numLocks = 1;
-         while (numLocks < configuration.getConcurrencyLevel())
-         {
-            ++tempLockSegShift;
-            numLocks <<= 1;
-         }
-         lockSegmentShift = 32 - tempLockSegShift;
-         lockSegmentMask = numLocks - 1;
-
-         initLocks(numLocks);
-      }
-
-      final int hashToIndex(Fqn fqn)
-      {
-         return (hash(fqn) >>> 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 fqn the object serving as a key
-       * @return the hash code
-       */
-      final int hash(Fqn fqn)
-      {
-         int h = fqn.hashCode();
-         h += ~(h << 9);
-         h ^= (h >>> 14);
-         h += (h << 4);
-         h ^= (h >>> 10);
-         return h;
-      }
-
-      abstract void initLocks(int numLocks);
-
-      abstract boolean ownsLock(Fqn fqn, Object owner);
-
-      abstract boolean isLocked(Fqn fqn);
-
-      abstract Lock getLock(Fqn fqn);
-
-      public abstract int getNumLocksHeld();
-   }
-
-   public class ReentrantLockContainer extends LockContainer
-   {
-      ReentrantLock[] sharedLocks;
-
-      void initLocks(int numLocks)
-      {
-         sharedLocks = new ReentrantLock[numLocks];
-         for (int i = 0; i < numLocks; i++) sharedLocks[i] = new ReentrantLock();
-      }
-
-      ReentrantLock getLock(Fqn fqn)
-      {
-         ReentrantLock l = sharedLocks[hashToIndex(fqn)];
-         if (trace) log.trace("Found lock " + l + " for fqn " + fqn);
-         return l;
-      }
-
-      public int getNumLocksHeld()
-      {
-         int i = 0;
-         for (ReentrantLock l : sharedLocks) if (l.isLocked()) i++;
-         return i;
-      }
-
-      boolean ownsLock(Fqn fqn, Object owner)
-      {
-         ReentrantLock lock = getLock(fqn);
-         return lock.isHeldByCurrentThread();
-      }
-
-      boolean isLocked(Fqn fqn)
-      {
-         ReentrantLock lock = getLock(fqn);
-         return lock.isLocked();
-      }
-
-      public String toString()
-      {
-         return "ReentrantLockContainer{" +
-               "sharedLocks=" + (sharedLocks == null ? null : Arrays.asList(sharedLocks)) +
-               '}';
-      }
-   }
-
-   public class OwnableReentrantLockContainer extends LockContainer
-   {
-      OwnableReentrantLock[] sharedLocks;
-
-      void initLocks(int numLocks)
-      {
-         sharedLocks = new OwnableReentrantLock[numLocks];
-         for (int i = 0; i < numLocks; i++) sharedLocks[i] = new OwnableReentrantLock(invocationContextContainer);
-      }
-
-      OwnableReentrantLock getLock(Fqn fqn)
-      {
-         OwnableReentrantLock l = sharedLocks[hashToIndex(fqn)];
-         if (trace) log.trace("Found lock " + l + " for fqn " + fqn);
-         return l;
-      }
-
-      boolean ownsLock(Fqn fqn, Object owner)
-      {
-         OwnableReentrantLock lock = getLock(fqn);
-         return owner.equals(lock.getOwner());
-      }
-
-      boolean isLocked(Fqn fqn)
-      {
-         OwnableReentrantLock lock = getLock(fqn);
-         return lock.isLocked();
-      }
-
-      public 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)) +
-               '}';
-      }
-   }
 }

Added: core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/LockContainer.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/LockContainer.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/LockContainer.java	2008-07-30 15:43:05 UTC (rev 6442)
@@ -0,0 +1,89 @@
+package org.jboss.cache.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 3.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 << 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();
+
+   /**
+    * Clears all locks held and re-initialises stripes.
+    */
+   public abstract void reset();
+}

Modified: core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/OwnableReentrantLock.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/OwnableReentrantLock.java	2008-07-30 15:42:20 UTC (rev 6441)
+++ core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/OwnableReentrantLock.java	2008-07-30 15:43:05 UTC (rev 6442)
@@ -42,6 +42,8 @@
     */
    public OwnableReentrantLock(InvocationContextContainer invocationContextContainer)
    {
+      if (invocationContextContainer == null)
+         throw new IllegalArgumentException("Invocation context container cannot be null!");
       this.invocationContextContainer = invocationContextContainer;
    }
 

Added: core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/OwnableReentrantLockContainer.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/OwnableReentrantLockContainer.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/OwnableReentrantLockContainer.java	2008-07-30 15:43:05 UTC (rev 6442)
@@ -0,0 +1,75 @@
+package org.jboss.cache.util.concurrent.locks;
+
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.cache.invocation.InvocationContextContainer;
+
+import java.util.Arrays;
+
+/**
+ * A LockContainer that holds {@link org.jboss.cache.util.concurrent.locks.OwnableReentrantLock}s.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @see org.jboss.cache.util.concurrent.locks.ReentrantLockContainer
+ * @see org.jboss.cache.util.concurrent.locks.OwnableReentrantLock
+ * @since 3.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);
+   }
+}

Added: core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/ReentrantLockContainer.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/ReentrantLockContainer.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/ReentrantLockContainer.java	2008-07-30 15:43:05 UTC (rev 6442)
@@ -0,0 +1,71 @@
+package org.jboss.cache.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.jboss.cache.util.concurrent.locks.OwnableReentrantLockContainer
+ * @since 3.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 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);
+   }
+}

Modified: core/trunk/src/test/java/org/jboss/cache/api/mvcc/LockAssert.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/mvcc/LockAssert.java	2008-07-30 15:42:20 UTC (rev 6441)
+++ core/trunk/src/test/java/org/jboss/cache/api/mvcc/LockAssert.java	2008-07-30 15:43:05 UTC (rev 6442)
@@ -3,8 +3,8 @@
 import org.jboss.cache.Fqn;
 import org.jboss.cache.invocation.InvocationContextContainer;
 import org.jboss.cache.lock.LockManager;
-import org.jboss.cache.lock.MVCCLockManager.LockContainer;
 import org.jboss.cache.util.TestingUtil;
+import org.jboss.cache.util.concurrent.locks.LockContainer;
 
 /**
  * Helper class to assert lock status in MVCC

Modified: core/trunk/src/test/java/org/jboss/cache/lock/MVCCLockManagerRecordingTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/lock/MVCCLockManagerRecordingTest.java	2008-07-30 15:42:20 UTC (rev 6441)
+++ core/trunk/src/test/java/org/jboss/cache/lock/MVCCLockManagerRecordingTest.java	2008-07-30 15:43:05 UTC (rev 6442)
@@ -4,9 +4,9 @@
 import org.jboss.cache.config.Configuration;
 import org.jboss.cache.factories.context.MVCCContextFactory;
 import org.jboss.cache.invocation.InvocationContextContainer;
-import org.jboss.cache.lock.MVCCLockManager.LockContainer;
 import org.jboss.cache.transaction.DummyTransactionManager;
 import org.jboss.cache.util.TestingUtil;
+import org.jboss.cache.util.concurrent.locks.LockContainer;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 




More information about the jbosscache-commits mailing list