Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / impl / store / raw / xact / RowLocking2.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/store/raw/xact/RowLocking2.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/store/raw/xact/RowLocking2.java
new file mode 100644 (file)
index 0000000..9f70fcd
--- /dev/null
@@ -0,0 +1,220 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.store.raw.xact.RowLocking2\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.store.raw.xact;\r
+\r
+import org.apache.derby.iapi.services.locks.LockFactory;\r
+import org.apache.derby.iapi.services.locks.C_LockFactory;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.store.raw.ContainerHandle;\r
+import org.apache.derby.iapi.store.raw.ContainerLock;\r
+import org.apache.derby.iapi.store.raw.LockingPolicy;\r
+import org.apache.derby.iapi.store.raw.RecordHandle;\r
+import org.apache.derby.iapi.store.raw.RowLock;\r
+import org.apache.derby.iapi.store.raw.Transaction;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+\r
+/**\r
+       A locking policy that implements row level locking with isolation degree 2.\r
+\r
+    The approach is to place all "write" container and row locks on the \r
+    transaction group lock list.  Locks on this group will last until end\r
+    of transaction.  All "read" container and row locks will be placed \r
+    on a group list, key'd by the ContainerId of the lock.  Locks on this\r
+    list will either be released explicitly by the caller, or will be released\r
+    as a group when the unlockContainer() call is made.\r
+\r
+    Note that write operations extend from the RowLocking3 implementations.\r
+\r
+       @see org.apache.derby.iapi.store.raw.LockingPolicy\r
+*/\r
+public class RowLocking2 extends RowLockingRR\r
+{\r
+       // no locking has no state, so it's safe to hold\r
+       // it as a static\r
+       private static final LockingPolicy NO_LOCK = new NoLocking();\r
+\r
+       protected RowLocking2(LockFactory lf) \r
+    {\r
+               super(lf);\r
+       }\r
+\r
+    /**\r
+     * Obtain container level intent lock.\r
+     * <p>\r
+     * This implementation of row locking is 2 level, ie. table and row locking.\r
+     * It will interact correctly with tables opened with ContainerLocking3\r
+     * locking mode.\r
+     * <p>\r
+     * Updater's will get table level IX locks, and X row locks.\r
+     * <p>\r
+     * Reader's will get table level IS locks, and S row locks.\r
+     * <p>\r
+     * Read locks are put in a separate "group" from the transaction, so that\r
+     * when the container is closed it can release these read locks.\r
+     *\r
+     * @param t            Transaction to associate lock with.\r
+     * @param container    Container to lock.\r
+     * @param waitForLock  Should lock request wait until granted?\r
+     * @param forUpdate    Should container be locked for update, or read?\r
+     *\r
+     * @return true if the lock was obtained, false if it wasn't. \r
+     *   False should only be returned if the waitForLock policy was set to\r
+     *  "false," and the lock was unavailable.\r
+     *\r
+        * @exception  StandardException  Standard exception policy.\r
+     **/\r
+       public boolean lockContainer(\r
+    Transaction         t, \r
+    ContainerHandle     container, \r
+    boolean             waitForLock,\r
+    boolean             forUpdate)\r
+               throws StandardException \r
+    {\r
+               Object qualifier = forUpdate ? ContainerLock.CIX : ContainerLock.CIS;\r
+\r
+        // for cursor stability put read locks on a separate lock chain, which\r
+        // will be released when the container is unlocked.\r
+        Object group = \r
+            forUpdate ? ((Object) t) : ((Object) container.getUniqueId());\r
+\r
+               boolean gotLock = \r
+            lf.lockObject(\r
+                t.getCompatibilitySpace(), group, container.getId(), qualifier,\r
+                waitForLock ? C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT);\r
+\r
+               if (gotLock) \r
+        {\r
+                       // look for covering table locks\r
+                       // CIS and CIX is covered by CX \r
+            // In that case move the lock to the transaction list from the\r
+            // container list, as the null locking policy will do nothing in\r
+            // unlockContainer().\r
+            //\r
+\r
+\r
+                       if (lf.isLockHeld(t.getCompatibilitySpace(), t, container.getId(),\r
+                                                         ContainerLock.CX))\r
+                       {\r
+                               //release any container group locks becuase CX container lock will cover everthing.\r
+                               lf.unlockGroup(t.getCompatibilitySpace(), container.getUniqueId());\r
+                               container.setLockingPolicy(NO_LOCK);\r
+                       }else if ((!forUpdate) && \r
+                                        lf.isLockHeld(t.getCompatibilitySpace(), t, container.getId(), ContainerLock.CS))\r
+            {\r
+                // move locks from container group to transaction group.\r
+                               lf.transfer(t.getCompatibilitySpace(), group, t);\r
+                               container.setLockingPolicy(NO_LOCK);\r
+                       }\r
+               }\r
+\r
+               return gotLock;\r
+       }\r
+\r
+\r
+    /**\r
+     * Obtain lock on record being read.\r
+     * <p>\r
+     * Assumes that a table level IS has been acquired.  Will acquire a Shared\r
+     * or Update lock on the row, depending on the "forUpdate" parameter.\r
+     * <p>\r
+     * Read lock will be placed on separate group from transaction.\r
+     *\r
+     * @param t             The transaction to associate the lock with.\r
+     * @param record        The record to be locked.\r
+     * @param waitForLock   Should lock request wait until granted?\r
+     * @param forUpdate     Whether to open for read or write access.\r
+     *\r
+     * @return true if the lock was granted, false if waitForLock was false \r
+     * and the lock could not be granted.\r
+     *\r
+        * @exception  StandardException  Standard exception policy.\r
+     **/\r
+       public boolean lockRecordForRead(\r
+    Transaction     t, \r
+    ContainerHandle container_handle,\r
+    RecordHandle    record, \r
+    boolean         waitForLock,\r
+    boolean         forUpdate)\r
+               throws StandardException\r
+       {\r
+               Object qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2;\r
+\r
+        return( \r
+            lf.lockObject(\r
+                t.getCompatibilitySpace(), \r
+                container_handle.getUniqueId(), \r
+                record, \r
+                qualifier,\r
+                waitForLock ? \r
+                    C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT));\r
+       }\r
+\r
+       public void unlockRecordAfterRead(\r
+    Transaction     t, \r
+    ContainerHandle container_handle,\r
+    RecordHandle    record, \r
+    boolean         forUpdate,\r
+    boolean         row_qualified)\r
+        throws StandardException\r
+       {\r
+               Object qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2;\r
+\r
+        int count = \r
+            lf.unlock(\r
+                t.getCompatibilitySpace(), container_handle.getUniqueId(), \r
+                record, qualifier);\r
+\r
+        if (SanityManager.DEBUG)\r
+        {\r
+            // in the case of lock escalation the count could be 0.\r
+            if (!(count == 1 || count == 0))\r
+                       {\r
+                               SanityManager.THROWASSERT(\r
+                "count = " + count +\r
+                "record.getContainerId() = " + record.getContainerId());\r
+                       }\r
+        }\r
+       }\r
+\r
+    /**\r
+     * Unlock read locks.\r
+     * <p>\r
+     * In Cursor stability release all read locks obtained.  unlockContainer()\r
+     * will be called when the container is closed.\r
+     * <p>\r
+     *\r
+     * @param t                 The transaction to associate the lock with.\r
+     * @param container_handle  Container to unlock.\r
+     **/\r
+       public void unlockContainer(\r
+    Transaction     t, \r
+    ContainerHandle container_handle)\r
+    {\r
+        // Only release read locks before end of transaction in level 2.\r
+        lf.unlockGroup(\r
+            t.getCompatibilitySpace(), container_handle.getUniqueId());\r
+       }\r
+}\r