Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / store / raw / data / PageBasicOperation.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/store/raw/data/PageBasicOperation.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/store/raw/data/PageBasicOperation.java
new file mode 100644 (file)
index 0000000..83b4078
--- /dev/null
@@ -0,0 +1,407 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.store.raw.data.PageBasicOperation\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.data;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import org.apache.derby.impl.store.raw.data.BasePage;\r
+\r
+import org.apache.derby.iapi.store.raw.ContainerHandle;\r
+import org.apache.derby.iapi.store.raw.LockingPolicy;\r
+import org.apache.derby.iapi.store.raw.Loggable;\r
+import org.apache.derby.iapi.store.raw.Page;\r
+import org.apache.derby.iapi.store.raw.RePreparable;\r
+import org.apache.derby.iapi.store.raw.Transaction;\r
+import org.apache.derby.iapi.store.raw.PageKey;\r
+\r
+import org.apache.derby.iapi.store.raw.xact.RawTransaction;\r
+import org.apache.derby.iapi.store.raw.data.RawContainerHandle;\r
+import org.apache.derby.iapi.store.raw.log.LogInstant;\r
+import org.apache.derby.iapi.store.raw.RawStoreFactory;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+\r
+import org.apache.derby.iapi.services.io.CompressedNumber;\r
+import org.apache.derby.iapi.util.ByteArray;\r
+import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;\r
+import org.apache.derby.iapi.services.property.PropertyUtil;\r
+\r
+import java.io.InputStream;\r
+import java.io.ObjectOutput;\r
+import java.io.ObjectInput;\r
+import java.io.IOException;\r
+import org.apache.derby.iapi.services.io.LimitObjectInput;\r
+\r
+/**\r
+    A PageBasicOperation changed the content of a page, this is the root class of all\r
+       page oriented operation. Each PageBasicOperation record change(s)\r
+       that apply to <B>one and only one page</B>.  The pageID that is changed\r
+       must be recorded in the log operation - in other words, redo\r
+       must be physical (or more correctly, in Gray's term, physiological, since\r
+       changes are logical <B>within</B> a page).\r
+       <BR>Undo can be logical, but the undo logic must be hidden in\r
+       generateUndo. By the time a compensation operation is logged as a\r
+       LogOperation, the page that needs roll back must be determined.\r
+\r
+       <PRE>\r
+       @format_id      no format id, an abstract class.\r
+       @purpose        provide methods for logical undo\r
+       @upgrade\r
+       @disk_layout\r
+               pageId(PageKey)                 the page this operation applies to\r
+               pageVersion(CompressedLong)     the page version this operation applied to\r
+               OptionalData    none\r
+       @end_format\r
+       </PRE>\r
+\r
+       @see Loggable\r
+*/\r
+\r
+public abstract class PageBasicOperation implements Loggable, RePreparable \r
+{\r
+\r
+\r
+       /* page info this operation changed */\r
+       private PageKey     pageId;\r
+       private long        pageVersion;\r
+\r
+\r
+       /* runtime page and data necessary to maintain it */\r
+       transient protected BasePage            page;\r
+       transient protected RawContainerHandle  containerHdl;\r
+       transient protected boolean                 foundHere;\r
+\r
+       protected PageBasicOperation(BasePage page) \r
+    {\r
+               if (SanityManager.DEBUG) \r
+        {\r
+                       SanityManager.ASSERT(\r
+                page != null, \r
+                "cannot create page operation on a null page pointer");\r
+               }\r
+\r
+        // runtime info\r
+               this.page = page;\r
+\r
+        // info which will be logged.\r
+               pageId      = page.getPageId();\r
+               pageVersion = page.getPageVersion();\r
+       }\r
+\r
+       // no-arg constructor, required by Formatable\r
+       public PageBasicOperation() \r
+    {\r
+       }\r
+\r
+       public String toString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       return "Page Operation: " + pageId.toString() +\r
+                               " pageVersion " + pageVersion + " : ";\r
+               }\r
+               else\r
+                       return null;\r
+       }\r
+\r
+       /*\r
+        * Formatable methods\r
+        */\r
+\r
+\r
+       public void writeExternal(ObjectOutput out) throws IOException\r
+       {\r
+               pageId.writeExternal(out);\r
+               CompressedNumber.writeLong(out, pageVersion);\r
+       }\r
+\r
+       public void readExternal(ObjectInput in) \r
+        throws IOException, ClassNotFoundException\r
+       {\r
+               pageId = PageKey.read(in);\r
+\r
+               pageVersion = CompressedNumber.readLong(in);\r
+       }\r
+\r
+       /*\r
+        * Loggable methods\r
+        */\r
+\r
+       /** Returns true if this op should be redone during recovery redo,\r
+           if so, get and latched the page.\r
+\r
+               @exception StandardException Standard Derby policy.\r
+        */\r
+       public final boolean needsRedo(Transaction xact)\r
+                throws StandardException\r
+       {\r
+               if (findpage(xact) == null)     // committed dropped container\r
+                       return false;\r
+\r
+               long pversion = page.getPageVersion();\r
+               if (pversion == pageVersion)\r
+                       return true;\r
+\r
+               releaseResource(xact);\r
+\r
+               if (pversion > pageVersion)\r
+                       return false;\r
+               else\r
+                       throw StandardException.newException(\r
+                    SQLState.DATA_MISSING_LOG, pageId, \r
+                    new Long(pversion), \r
+                    new Long(pageVersion));\r
+       }\r
+\r
+       /** Release latched page and any other resources acquired during a previous\r
+               findpage, safe to call multiple times.\r
+\r
+               In this RawStore implementataion, resource is acquired by a log\r
+               operation in one of two places\r
+               <nl>\r
+               <li> during runtime or recovery undo in PageOperation.generateUndo()\r
+               <li> during recovery redo in PageBasicOperation.needsRedo()\r
+               </nl>\r
+        */\r
+       public void releaseResource(Transaction xact)\r
+       {\r
+               if (!foundHere)                 // don't release anything not found by this\r
+                       return;\r
+\r
+               if (page != null)\r
+               {\r
+                       page.unlatch();\r
+                       page = null;\r
+               }\r
+\r
+               if (containerHdl != null)\r
+               {\r
+                       containerHdl.close();\r
+                       containerHdl = null;\r
+               }\r
+\r
+               foundHere = false;\r
+       }\r
+\r
+       /**\r
+               A page operation is a RAWSTORE log record\r
+       */\r
+       public int group()\r
+       {\r
+               return(Loggable.RAWSTORE | Loggable.XA_NEEDLOCK);\r
+       }\r
+\r
+       /**\r
+               the default for optional data is set to null.  If an operation has optional data,\r
+               the operation need to prepare the optional data for this method.\r
+\r
+               WARNING: If a log operation extends this class, and the operation has optional data,\r
+               it MUST overwrite this method to return a ByteArray that contains the optional data. \r
+\r
+               @exception StandardException Standard Derby policy.\r
+       */\r
+       public ByteArray getPreparedLog() throws StandardException\r
+       {\r
+               return (ByteArray) null;\r
+       }\r
+\r
+    /**************************************************************************\r
+     * Public Methods of RePreparable Interface:\r
+     **************************************************************************\r
+     */\r
+\r
+    /**\r
+     * reclaim locks associated with the changes in this log record.\r
+     * <p>\r
+     *\r
+        * @exception  StandardException  Standard exception policy.\r
+     **/\r
+    public void reclaimPrepareLocks(\r
+    Transaction     t,\r
+    LockingPolicy   locking_policy)\r
+               throws StandardException\r
+    {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.DEBUG_PRINT("", "PageBasicOperation.reclaimPrepareLocks().");\r
+    }\r
+\r
+       /*\r
+        *      Methods specific to this class\r
+        */\r
+                \r
+       /**\r
+               Reset the pageNumber\r
+       */\r
+       protected final void resetPageNumber(long pageNumber)\r
+       {\r
+               pageId = new PageKey(pageId.getContainerId(), pageNumber);\r
+       }\r
+\r
+       protected final PageKey getPageId() {\r
+               return pageId;\r
+       }\r
+\r
+       /** Find the page the operation applies to and latch it, this only\r
+           uses the segmentId, containerId, and pageId stored in this log\r
+               record to find the page.\r
+\r
+               @return null if container is dropped and committed (possibly\r
+               stubbified), else return the latched page\r
+\r
+               @exception StandardException Standard Derby policy.\r
+        */\r
+       public final BasePage findpage(Transaction xact) throws StandardException \r
+       {\r
+               releaseResource(xact);\r
+\r
+               RawTransaction rtran = (RawTransaction)xact;\r
+               containerHdl = rtran.openDroppedContainer(pageId.getContainerId(),\r
+                       (LockingPolicy) null);\r
+\r
+               if (containerHdl == null)\r
+        {\r
+                       throw StandardException.newException(\r
+                    SQLState.DATA_CONTAINER_VANISHED, pageId.getContainerId());\r
+        }\r
+\r
+               foundHere = true;\r
+\r
+               // if container is dropped and committed, cannot look at any page, \r
+        // it may be a container stub\r
+               if (containerHdl.getContainerStatus() == RawContainerHandle.COMMITTED_DROP)\r
+               {\r
+                       releaseResource(xact);\r
+                       return null;\r
+               }\r
+\r
+               StandardException getPageException = null;\r
+               try\r
+               {\r
+                       // get and latch page - we don't know the status of the page or what\r
+                       // kind of page we are looking for, get any type of page\r
+                       page = (BasePage)(containerHdl.getAnyPage(pageId.getPageNumber()));\r
+               }\r
+               catch (StandardException se)\r
+               {\r
+                       getPageException = se;\r
+               }\r
+                       \r
+               //Try to initialize the page if page not found exception occurs during\r
+               //recovery and the page version is zero(Init Page).\r
+               //We do this if derby.storage.patchInitPageRecoverError is set.\r
+               if (page == null && getPageException != null && pageVersion == 0)\r
+                       if (PropertyUtil.getSystemBoolean(RawStoreFactory.PATCH_INITPAGE_RECOVER_ERROR))\r
+                               page = getPageForRedoRecovery(xact);\r
+               \r
+               // maybe we are in rollforward recovery and this is an init page operation,\r
+               // give subclass a chance to create the page\r
+               if (page == null && getPageException != null)\r
+               {\r
+                       //if are rolloforward recovery reload the page using load tran methods\r
+                       //that initialize the page. because in rollforward recovery, we \r
+                       //might be actually recreating the page container did not exist \r
+                       //in the backup when we started the rollforward recovery.\r
+\r
+                       if (rtran.inRollForwardRecovery())\r
+                       {\r
+                               if (SanityManager.DEBUG) \r
+                                       if(SanityManager.DEBUG_ON("LoadTran"))\r
+                                               SanityManager.DEBUG_PRINT(\r
+                            "Trace", "got null page " + pageId + \r
+                            " and getPageException, attempt last ditch effort");\r
+\r
+                               page = getPageForRedoRecovery(xact);\r
+                               \r
+                               if (SanityManager.DEBUG) \r
+                                       if(SanityManager.DEBUG_ON("LoadTran"))\r
+                                               SanityManager.DEBUG_PRINT(\r
+                            "Trace"," getPageForRedoRecovery, got page=" + \r
+                            (page != null));\r
+                       }       \r
+               }\r
+\r
+               if (page == null)\r
+               {\r
+                       if (getPageException != null)\r
+            {\r
+                               throw getPageException; // that is the original error\r
+            }\r
+                       else\r
+            {\r
+                               throw StandardException.newException(\r
+                        SQLState.DATA_MISSING_PAGE, pageId);\r
+            }\r
+               }\r
+\r
+               return page;\r
+       }\r
+\r
+       /**\r
+               Subclass (e.g., init page) that wishes to do something about missing\r
+               pages in load tran should override this method to return the page\r
+\r
+               @exception StandardException Derby Standard error policy\r
+        */\r
+       protected BasePage getPageForRedoRecovery(Transaction xact)\r
+                throws StandardException\r
+       {\r
+               return null;\r
+       }\r
+\r
+       public final Page getPage() {\r
+               return page;\r
+       }\r
+\r
+       public final long getPageVersion() {\r
+               return pageVersion;\r
+       }\r
+\r
+\r
+       /**\r
+               Undo the change indicated by this log operation and optional data.\r
+               The page the undo should apply to is the latched undoPage.\r
+               The undoPage must be the same page as the doMe page and the undo\r
+               operation must restore the before image of the row that changed.  \r
+\r
+               <BR> this can only be used under special circumstances: namely\r
+               table level locking, and no internal or nested transaction, and all\r
+               operations are rollec back with restoreMe instead of undoMe.\r
+\r
+               <BR><B>This method is here to support BeforeImageLogging</B>\r
+\r
+               @param xact                     the Transaction doing the rollback\r
+               @param undoPage         the page to rollback changes on\r
+               @param CLRinstant       the log instant of this (PageUndo) operation\r
+               @param in                       optional data for the rollback operation\r
+\r
+               @exception IOException Can be thrown by any of the methods of ObjectInput.\r
+               @exception StandardException Standard Derby policy.             \r
+       */\r
+       abstract public void restoreMe(Transaction xact, BasePage undoPage,\r
+                                                               LogInstant CLRinstant, LimitObjectInput in) \r
+                throws StandardException, IOException;\r
+\r
+\r
+}\r