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 / TransactionTableEntry.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/store/raw/xact/TransactionTableEntry.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/store/raw/xact/TransactionTableEntry.java
new file mode 100644 (file)
index 0000000..c91ce16
--- /dev/null
@@ -0,0 +1,560 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.store.raw.xact.TransactionTableEntry\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.sanity.SanityManager;\r
+import org.apache.derby.iapi.services.io.Formatable;\r
+import org.apache.derby.iapi.services.io.FormatIdUtil;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+import org.apache.derby.iapi.sql.conn.StatementContext;\r
+import org.apache.derby.iapi.store.access.TransactionInfo;\r
+import org.apache.derby.iapi.store.raw.GlobalTransactionId;\r
+import org.apache.derby.iapi.store.raw.xact.TransactionId;\r
+import org.apache.derby.iapi.store.raw.log.LogInstant;\r
+\r
+import java.io.ObjectOutput;\r
+import java.io.ObjectInput;\r
+import java.io.IOException;\r
+\r
+/**\r
+       Transaction table entry is used to store all relavent information of a\r
+       transaction into the transaction table for the use of checkpoint, recovery,\r
+       Transaction management during Quiesce state, and for dumping transaction table.  Only works\r
+       with the following classes: TransactionTable, XactFactory, Xact\r
+       <BR>\r
+       During run time, whenever any transaction is started, it is put into the\r
+       transaction table.  Whenever any transaction is closed, it is removed from\r
+       the transaction table.\r
+\r
+\r
+*/\r
+\r
+public class TransactionTableEntry implements Formatable, TransactionInfo, Cloneable\r
+{\r
+       // These fields are only populated if this TTE has been read in from the\r
+       // log.  Otherwise, they are gotten from the transaction object myxact.\r
+       private TransactionId           xid;\r
+       private GlobalTransactionId     gid;\r
+       private LogInstant              firstLog;\r
+       private LogInstant              lastLog;\r
+\r
+       // this field is always present - it is 0 for read only transaction, this\r
+    // is a copy of the status from the Xact (the copy is necessary as during\r
+    // recovery the Xact is shared by all transaction table entries during\r
+    // redo and undo).\r
+       private int                     transactionStatus;\r
+\r
+       // fields useful for returning transaction information if read from \r
+    // transaction log during recovery\r
+       private transient Xact    myxact; \r
+       private transient boolean update;\r
+       private transient boolean recovery;         // is this a transaction read \r
+                                                // from the log during recovery?\r
+       private transient boolean needExclusion;    // in a quiesce state , this \r
+                                                // transaction needs to be \r
+                                                // barred from activation \r
+                                                // during quiesce state\r
+\r
+       private boolean isClone;                            // am I a clone made for the \r
+                                                // TransactionVTI?\r
+\r
+       private transient LanguageConnectionContext lcc;\r
+\r
+\r
+       /* package */\r
+       // entry attribute\r
+       static final int UPDATE         = 0x1;\r
+       static final int RECOVERY       = 0x2;\r
+       static final int EXCLUDE        = 0x4;\r
+\r
+       TransactionTableEntry(\r
+    Xact            xact, \r
+    TransactionId   tid, \r
+    int             status, \r
+    int             attribute)\r
+       {\r
+               myxact              = xact;\r
+               xid                 = tid;\r
+               transactionStatus   = status;\r
+\r
+               update              = (attribute & UPDATE)   != 0;\r
+               needExclusion       = (attribute & EXCLUDE)  != 0;\r
+               recovery            = (attribute & RECOVERY) != 0;\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(tid != null, "tid is null");\r
+                       if (update && xact.getFirstLogInstant() == null)\r
+            {\r
+                               SanityManager.THROWASSERT(\r
+                    "update transaction has firstLog = null");\r
+            }\r
+\r
+\r
+            /*\r
+                       if (!update && xact.getFirstLogInstant() != null)\r
+            {\r
+                               SanityManager.THROWASSERT(\r
+                    "read only transaction has firstLog = " + \r
+                    xact.getFirstLogInstant());\r
+            }\r
+            */\r
+               }\r
+\r
+               // Normally, we don't need to remember the gid, firstLog and lastLog\r
+               // because myxact will have the same information.  However, in\r
+               // recovery, there is only one transaction taking on different identity\r
+               // as the log is replayed.  Then each transaction table entry has keep\r
+               // its own identity and not rely on myxact.  These recovery\r
+               // transactions are materialized in the transaction table via a\r
+               // readObject in the checkpoint log record, or are added by\r
+               // addUpdateTransaction when the log is scanned.\r
+               if (recovery)\r
+               {\r
+                       // make a copy of everything\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               SanityManager.ASSERT(update, "recovery but not update");\r
+\r
+                               if (tid != xact.getId())\r
+                {\r
+                    SanityManager.THROWASSERT(\r
+                        "adding a update transaction during recovery " + \r
+                        " but the tids doesn't match" +\r
+                        tid + " " + xact.getId());\r
+                }\r
+                       }\r
+\r
+                       gid         = xact.getGlobalId();\r
+                       firstLog    = xact.getFirstLogInstant();\r
+                       lastLog     = xact.getLastLogInstant();\r
+               }\r
+       }\r
+\r
+       /*\r
+        * Formatable methods\r
+        */\r
+       public TransactionTableEntry()\r
+       { }\r
+\r
+       public void writeExternal(ObjectOutput out) throws IOException\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(!recovery, "writing out a recovery transaction");\r
+                       SanityManager.ASSERT(update, "writing out read only transaction");\r
+                       SanityManager.ASSERT(myxact.getFirstLogInstant() != null, \r
+                                                                "myxact.getFirstLogInstant is null");\r
+                       SanityManager.ASSERT(!isClone, "cannot write out a clone");\r
+               }\r
+\r
+               // Why is is safe to access first and last log instant in myxact while\r
+               // this is happening?  Because we only writes out update transaction\r
+               // during run time.  When a read only transactions becomes an update\r
+               // transaction , or when an update transaction commits, the beginXact\r
+               // and endXact log record's doMe method will try to change the\r
+               // transaction table entry's state to updat and non-update\r
+               // respectively.  That change needs to go thru the transaction table\r
+               // which is mutually exclusive to writing out the transaction table.\r
+               // Since we are only looking at update transactions and it is "stuck"\r
+               // in update state in the middle of a TransactionTable.writeExternal\r
+               // call, all the fields we access in myxact is stable (actually the xid\r
+               // is also stable but we already have it).\r
+               //\r
+               out.writeObject(xid);\r
+               out.writeObject(myxact.getGlobalId());\r
+               out.writeObject(myxact.getFirstLogInstant());\r
+               out.writeObject(myxact.getLastLogInstant());\r
+               out.writeInt(transactionStatus);\r
+       }\r
+\r
+       public void readExternal(ObjectInput in) \r
+                throws ClassNotFoundException, IOException\r
+       {\r
+               // the only time a transaction table entry is written out is to the\r
+               // log, so this must be read in during recovery.\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClone, "cannot write out a clone");\r
+\r
+               xid = (TransactionId)in.readObject();\r
+               gid = (GlobalTransactionId)in.readObject();\r
+               firstLog = (LogInstant)in.readObject();\r
+               lastLog = (LogInstant)in.readObject();\r
+               transactionStatus = in.readInt();\r
+               update = true;\r
+               recovery = true;\r
+               needExclusion = true;\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(xid != null, "read in transaction table entry with null id");\r
+                       SanityManager.ASSERT(firstLog != null, "read in transaction table entry with firstLog");\r
+               }\r
+\r
+       }\r
+\r
+\r
+       // set my transaction instance variable for a recovery transaction\r
+       void setXact(Xact xact)\r
+       {\r
+        /*\r
+        RESOLVE (mikem) - prepared transactions now call setXact() when they are\r
+        not in recovery.\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(recovery, \r
+                                                                "setting non-recovery transaction table entry xact");\r
+                       SanityManager.ASSERT(!isClone, "cannot setXact with a clone");\r
+               }\r
+        */\r
+               myxact = xact;\r
+\r
+       }\r
+\r
+       /**\r
+               Return my format identifier.\r
+       */\r
+       public int getTypeFormatId() {\r
+               return StoredFormatIds.RAW_STORE_TRANSACTION_TABLE_ENTRY;\r
+       }\r
+\r
+       public String toString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       StringBuffer str = new StringBuffer(500).\r
+                               append("Xid=").append(getXid()).\r
+                               append(" gid=").append(getGid()).\r
+                               append(" firstLog=").append(getFirstLog()).\r
+                               append(" lastLog=").append(getLastLog()).\r
+                               append(" transactionStatus=").append(transactionStatus).\r
+                               append(" myxact=").append(myxact).\r
+                               append(" update=").append(update).\r
+                               append(" recovery=").append(recovery).\r
+                               append(" prepare=").append(isPrepared()).\r
+                               append(" needExclusion=").append(needExclusion).\r
+                               append("\n");\r
+                       return str.toString();\r
+               }\r
+               else\r
+                       return null;\r
+       }\r
+\r
+       void updateTransactionStatus(Xact xact, int status, int attribute)\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(myxact == xact,\r
+                               "update transaction status for wrong xact");\r
+                       SanityManager.ASSERT(!isClone, "cannot change a clone");\r
+               }\r
+\r
+               this.update = (attribute & UPDATE) != 0;\r
+       }\r
+\r
+       void removeUpdateTransaction()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClone, "cannot change a clone");\r
+\r
+               this.update = false;\r
+               transactionStatus = 0;\r
+               \r
+       }\r
+\r
+       void unsetRecoveryStatus()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClone, "cannot change a clone");\r
+\r
+        // RESOLVE (mikem) - this is kind of ugly. move to a better place?\r
+\r
+        firstLog = null;\r
+\r
+               this.recovery = false;\r
+       }\r
+\r
+       void prepareTransaction()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClone, "cannot change a clone");\r
+\r
+               transactionStatus |= Xact.END_PREPARED;\r
+       }\r
+\r
+    /**************************************************************************\r
+     * get instance variables\r
+     **************************************************************************\r
+     */\r
+\r
+       TransactionId getXid()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(xid != null, "TTE with null xid");\r
+                       SanityManager.ASSERT(!isClone, "cannot call method with a clone");\r
+               }\r
+\r
+               return xid;\r
+       }\r
+\r
+       public final GlobalTransactionId getGid()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClone, "cannot call method with a clone");\r
+\r
+               if (gid != null)\r
+                       return gid;\r
+\r
+               if (myxact != null)\r
+                       return myxact.getGlobalId();\r
+\r
+               return null;\r
+       }\r
+\r
+       LogInstant getFirstLog()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(!isClone, "cannot call method with a clone");\r
+\r
+                       if (recovery)\r
+            {\r
+                               SanityManager.ASSERT(\r
+                    firstLog != null, \r
+                    "a recovery transaction with a null firstLog");\r
+            }\r
+                       else\r
+            {\r
+                               SanityManager.ASSERT(\r
+                    firstLog == null, \r
+                    "a normal transaction with a non-null firstLog" +\r
+                    "myxact.getFirstLogInstant() = " + myxact.getFirstLogInstant());\r
+            }\r
+               }\r
+\r
+               if (firstLog != null)\r
+                       return firstLog;\r
+\r
+               if (myxact != null)\r
+                       return myxact.getFirstLogInstant();\r
+\r
+               return null;\r
+       }\r
+\r
+       LogInstant getLastLog()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClone, "cannot call method with a clone");\r
+\r
+               if (lastLog != null)\r
+                       return lastLog;\r
+\r
+               if (myxact != null)\r
+                       return myxact.getLastLogInstant();\r
+\r
+               return null;\r
+       }\r
+\r
+       public final Xact getXact()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClone, "cannot call method with a clone");\r
+\r
+               return myxact;\r
+       }\r
+\r
+       int getTransactionStatus()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClone, "cannot call method with a clone");\r
+\r
+               return transactionStatus;\r
+       }\r
+\r
+       boolean isUpdate()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClone, "cannot call method with a clone");\r
+\r
+               return update;\r
+       }\r
+\r
+       boolean isRecovery()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClone, "cannot call method with a clone");\r
+\r
+               return recovery;\r
+       }\r
+\r
+       boolean isPrepared()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClone, "cannot call method with a clone");\r
+\r
+               return((transactionStatus & Xact.END_PREPARED) != 0);\r
+       }\r
+\r
+\r
+\r
+\r
+       public boolean needExclusion()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClone, "cannot call method with a clone");\r
+\r
+               return needExclusion;\r
+       }\r
+\r
+       /**\r
+               Methods of TransactionInfo\r
+        */\r
+       public String getTransactionIdString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(\r
+                !recovery, "trying to display recovery transaction");\r
+                       SanityManager.ASSERT(myxact != null, "my xact is null");\r
+                       SanityManager.ASSERT(isClone, "Should only call method on a clone");\r
+               }\r
+\r
+               TransactionId t = myxact.getIdNoCheck();\r
+               return (t == null) ? "CLOSED" : t.toString();\r
+       }\r
+\r
+       public String getGlobalTransactionIdString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(\r
+                !recovery, "trying to display recovery transaction");\r
+                       SanityManager.ASSERT(myxact != null, "my xact is null");\r
+                       SanityManager.ASSERT(isClone, "Should only call method on a clone");\r
+               }\r
+\r
+               GlobalTransactionId gid = myxact.getGlobalId();\r
+               return (gid == null) ? null : gid.toString();\r
+       }\r
+\r
+       public String getUsernameString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(isClone, "Should only call method on a clone");\r
+\r
+               getlcc();\r
+               return (lcc == null) ? null : lcc.getAuthorizationId();\r
+       }\r
+\r
+       public String getTransactionTypeString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(isClone, "Should only call method on a clone");\r
+\r
+        if (myxact == null)\r
+            return null;\r
+        else if (myxact.getTransName() != null)\r
+            return myxact.getTransName();\r
+        else\r
+            return myxact.getContextId();\r
+       }\r
+\r
+       public String getTransactionStatusString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(isClone, "Should only call method on a clone");\r
+\r
+               return (myxact == null) ? null : myxact.getState();\r
+       }\r
+\r
+       public String getStatementTextString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(isClone, "Should only call method on a clone");\r
+\r
+               getlcc();\r
+               if (lcc != null)\r
+               {\r
+                       StatementContext sc = lcc.getStatementContext();\r
+                       if (sc != null)\r
+                               return sc.getStatementText() ;\r
+               }\r
+               return null;\r
+\r
+       }\r
+\r
+       public String getFirstLogInstantString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(isClone, "Should only call method on a clone");\r
+\r
+               LogInstant logInstant = \r
+            (myxact == null) ? null : myxact.getFirstLogInstant();\r
+\r
+               return (logInstant == null) ? null : logInstant.toString();\r
+\r
+       }               \r
+\r
+       private void getlcc()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(isClone, "Should only call method on a clone");\r
+\r
+               if (lcc == null && myxact != null && myxact.xc != null)\r
+               {\r
+                       XactContext xc = myxact.xc;\r
+\r
+                       lcc = (LanguageConnectionContext)\r
+                               xc.getContextManager().getContext(\r
+                    LanguageConnectionContext.CONTEXT_ID);\r
+               }\r
+       }\r
+\r
+       /**\r
+               Cloneable\r
+        */\r
+       protected Object clone()\r
+       {\r
+               try \r
+               {\r
+                       Object c = super.clone();\r
+                       ((TransactionTableEntry)c).isClone = true;\r
+\r
+                       return c;\r
+               }\r
+               catch (CloneNotSupportedException e) \r
+               {\r
+                       // this should not happen, we are cloneable\r
+                       if (SanityManager.DEBUG) \r
+            {\r
+                               SanityManager.THROWASSERT(\r
+                    "TransactionTableEntry cloneable but throws " +\r
+                                       "CloneNotSupportedException", e);\r
+                       }\r
+                       return null;\r
+               }                               \r
+       }\r
+}\r