Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / store / raw / data / InsertOperation.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/store/raw/data/InsertOperation.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/store/raw/data/InsertOperation.java
new file mode 100644 (file)
index 0000000..06d000c
--- /dev/null
@@ -0,0 +1,398 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.store.raw.data.InsertOperation\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
+import org.apache.derby.impl.store.raw.data.BasePage;\r
+import org.apache.derby.impl.store.raw.data.ReclaimSpace;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\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.store.access.conglomerate.LogicalUndo;\r
+\r
+import org.apache.derby.iapi.store.raw.PageKey;\r
+import org.apache.derby.iapi.store.raw.Compensation;\r
+import org.apache.derby.iapi.store.raw.Page;\r
+import org.apache.derby.iapi.store.raw.RecordHandle;\r
+import org.apache.derby.iapi.store.raw.Transaction;\r
+\r
+import org.apache.derby.iapi.store.raw.log.LogInstant;\r
+import org.apache.derby.iapi.store.raw.xact.RawTransaction;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\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.services.io.FormatableBitSet;\r
+import org.apache.derby.iapi.util.ByteArray;\r
+import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;\r
+import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;\r
+\r
+import java.io.OutputStream;\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
+/**    \r
+       Represents an insert of a record onto a page.\r
+\r
+       <PRE>\r
+       @format_id      LOGOP_INSERT\r
+               the formatId is written by FormatIdOutputStream when this object is\r
+               written out by writeObject\r
+       @purpose        insert a row onto a page\r
+       @upgrade\r
+       @disk_layout\r
+               LogicalPageOperation the superclass\r
+               doMeSlot(CompressedInt) which slot to operate on\r
+               insertFlat(byte)                to undo with purge or with delete\r
+\r
+               OptionalData    The after image of the row to be inserted.\r
+       @end_format\r
+       </PRE>\r
+    @see Page#insertAtSlot\r
+*/\r
+public final class InsertOperation extends LogicalPageOperation \r
+{\r
+\r
+       protected int                   doMeSlot;       // insert slot - only valid during doMe()\r
+       protected byte                  insertFlag;     // see page insertFlag\r
+       \r
+       /** next column that need to be inserted. */\r
+       transient protected int                 startColumn; \r
+\r
+       transient protected ByteArray preparedLog;\r
+\r
+       // yyz: revisit later, whether we need preparedLog, maybe everything will be prepared...\r
+       public InsertOperation(\r
+    RawTransaction              t, \r
+    BasePage                    page, \r
+    int                         slot, \r
+    int                         recordId,\r
+    Object[]       row, \r
+    FormatableBitSet                     validColumns,\r
+    LogicalUndo                 undo, \r
+    byte                        insertFlag, \r
+    int                         startColumn, \r
+    boolean                     isLongColumn,\r
+    int                         realStartColumn, \r
+    DynamicByteArrayOutputStream      logBuffer, \r
+    int                         realSpaceOnPage, \r
+    int                         overflowThreshold) \r
+               throws StandardException\r
+       {\r
+               super(page, undo, recordId);\r
+\r
+               this.doMeSlot = slot;\r
+               this.insertFlag = insertFlag;\r
+               this.startColumn = startColumn;\r
+\r
+               try {\r
+                       writeOptionalDataToBuffer(t, logBuffer, row, validColumns,\r
+                               isLongColumn, realStartColumn, realSpaceOnPage, overflowThreshold);\r
+               } catch (IOException ioe) {\r
+                       throw StandardException.newException(\r
+                    SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);\r
+               }\r
+       }\r
+\r
+       /*\r
+        * Formatable methods\r
+        */\r
+\r
+       // no-arg constructor, required by Formatable \r
+       public InsertOperation() { super(); }\r
+\r
+       /**\r
+               Write this out.\r
+               @exception IOException error writing to log stream\r
+       */\r
+       public void writeExternal(ObjectOutput out) throws IOException \r
+       {\r
+               super.writeExternal(out);\r
+               CompressedNumber.writeInt(out, doMeSlot);\r
+               out.writeByte(insertFlag);\r
+\r
+       }\r
+\r
+       /**\r
+               Read this in\r
+               @exception IOException error reading from log stream\r
+               @exception ClassNotFoundException log stream corrupted\r
+       */\r
+       public void readExternal(ObjectInput in) \r
+                throws IOException, ClassNotFoundException\r
+       {\r
+               super.readExternal(in);\r
+               doMeSlot = CompressedNumber.readInt(in);\r
+               insertFlag = in.readByte();\r
+       }\r
+\r
+       /**\r
+               Return my format identifier.\r
+       */\r
+       public int getTypeFormatId() {\r
+               return StoredFormatIds.LOGOP_INSERT;\r
+       }\r
+\r
+       /*\r
+        * Loggable methods\r
+        */\r
+       /**\r
+               @exception IOException Can be thrown by any of the methods of ObjectInput.\r
+               @exception StandardException Standard Derby policy.             \r
+         \r
+               @see org.apache.derby.iapi.store.raw.Loggable#doMe\r
+       */\r
+       public void doMe(Transaction xact, LogInstant instant, LimitObjectInput in)\r
+                throws StandardException, IOException \r
+       {\r
+               this.page.storeRecord(instant, doMeSlot, true, in);\r
+       }\r
+\r
+       /*\r
+        * PageOperation methods\r
+        */\r
+\r
+       /**\r
+               Undo the insert by simply marking the just inserted record as deleted.\r
+               All logical undo logic has already been taken care of by generateUndo.\r
+\r
+               @exception IOException Can be thrown by any of the methods of ObjectInput.\r
+               @exception StandardException Standard Derby policy.             \r
+\r
+               @see LogicalPageOperation#undoMe\r
+       */\r
+       public void undoMe(Transaction xact, BasePage undoPage, int undoRecordId,\r
+                                          LogInstant CLRInstant, LimitObjectInput in)\r
+                throws StandardException, IOException \r
+       {\r
+               int slot = \r
+            undoPage.findRecordById(undoRecordId, Page.FIRST_SLOT_NUMBER);\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       // if the record Id has changed, the page had better changed\r
+                       // this can only happen during recovery since in run time undo,\r
+                       // this resetRecordHandle gets called and this object have the new\r
+                       // page number and recordId\r
+                       if (undoRecordId != this.recordId)\r
+                               if (undoPage.getPageNumber() == getPageId().getPageNumber())\r
+                                       SanityManager.THROWASSERT(\r
+                                               "recordId changed from " + this.recordId +\r
+                                               " to " + undoRecordId +\r
+                                               " but page number did not change " +\r
+                                               undoPage.getPageNumber());\r
+\r
+                       if (slot == -1)\r
+                               SanityManager.THROWASSERT(\r
+                                       "recordId " +\r
+                                       undoRecordId +\r
+                                       " not found on page " +\r
+                                       undoPage.getPageNumber());\r
+               }\r
+\r
+               if ((insertFlag & Page.INSERT_UNDO_WITH_PURGE) != 0)\r
+               {\r
+                       undoPage.purgeRecord(CLRInstant, slot, undoRecordId);\r
+\r
+                       RawTransaction rxact = (RawTransaction)xact;\r
+\r
+                       // If we purged the last row off an overflow page, reclaim that\r
+                       // page - we have to do this post transaction termination because we\r
+                       // are underneath the log right now and cannot interrupt the log\r
+                       // stream.\r
+                       if (rxact.handlesPostTerminationWork() &&\r
+                               undoPage.isOverflowPage() && undoPage.recordCount() == 0)\r
+                       {\r
+                               ReclaimSpace work = \r
+                                       new ReclaimSpace(ReclaimSpace.PAGE, (PageKey)undoPage.getIdentity(),\r
+                                                                        rxact.getDataFactory(), true /* service ASAP */);\r
+                               rxact.addPostTerminationWork(work);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       undoPage.setDeleteStatus(CLRInstant, slot, true);\r
+               }\r
+\r
+               undoPage.setAuxObject(null);\r
+       }\r
+\r
+       /*\r
+        * LogicalUndoable methods\r
+        */\r
+\r
+\r
+       /**\r
+               Restore the row stored in the optional data of the log record.\r
+\r
+               @exception IOException error reading from log stream\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       public void restoreLoggedRow(Object[] row, LimitObjectInput in)\r
+               throws StandardException, IOException\r
+\r
+       {\r
+               Page p = null;\r
+\r
+               try {\r
+                       // the optional data is written by the page in the same format it\r
+                       // stores record on the page, \r
+                       // only a page knows how to restore a logged row back to a storable row\r
+                       // first get the page where the insert went even though the row may no\r
+                       // longer be there\r
+                       p = getContainer().getPage(getPageId().getPageNumber());\r
+\r
+                       ((BasePage)p).restoreRecordFromStream(in, row);\r
+\r
+               } finally {\r
+\r
+                       if (p != null) {\r
+                               p.unlatch();\r
+                               p = null;\r
+                       }\r
+               }\r
+       }\r
+\r
+       /*\r
+        * method to support BeforeImageLogging\r
+        */\r
+\r
+       /**\r
+        * restore the before image of the page\r
+        *\r
+        * @exception StandardException Standard Derby Error Policy\r
+        * @exception IOException problem reading the complete log record from the\r
+        * input stream\r
+        */\r
+\r
+       public void restoreMe(Transaction xact, BasePage undoPage, LogInstant CLRinstant, LimitObjectInput in)\r
+                throws StandardException, IOException\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       int slot = undoPage.findRecordById(recordId,Page.FIRST_SLOT_NUMBER);\r
+\r
+                       if ( ! getPageId().equals(undoPage.getPageId()))\r
+                               SanityManager.THROWASSERT(\r
+                                                               "restoreMe cannot restore to a different page. "\r
+                                                                + "doMe page:" + getPageId() + " undoPage:" + \r
+                                                                undoPage.getPageId());\r
+                       if (slot != doMeSlot)\r
+                               SanityManager.THROWASSERT(\r
+                                                               "restoreMe cannot restore to a different slot. "\r
+                                                                + "doMe slot:" + doMeSlot + " undoMe slot: " +\r
+                                                                slot + " recordId:" + recordId);\r
+               }\r
+               insertFlag |= Page.INSERT_UNDO_WITH_PURGE;\r
+\r
+               // undo the insert with purge.\r
+               undoMe(xact, undoPage, recordId, CLRinstant, in);\r
+       }\r
+\r
+       /*\r
+               methods to support prepared log\r
+               \r
+               the following two methods should not be called during recover\r
+       */\r
+\r
+       public ByteArray getPreparedLog()\r
+       {\r
+               return (this.preparedLog);\r
+       }\r
+\r
+\r
+       public int getNextStartColumn()\r
+       {\r
+               return (this.startColumn);\r
+       }\r
+       \r
+       /**\r
+               Writes out the row that is to be inserted as the optional data.\r
+\r
+               @exception IOException Can be thrown by any of the methods of ObjectOutput\r
+               @exception StandardException Standard Derby policy.             \r
+       */\r
+       private void writeOptionalDataToBuffer(\r
+    RawTransaction          t, \r
+    DynamicByteArrayOutputStream  logBuffer,\r
+    Object[]   row, \r
+    FormatableBitSet                 validColumns, \r
+    boolean                 isLongColumn,\r
+    int                     realStartColumn, \r
+    int                     realSpaceOnPage, \r
+    int                     overflowThreshold)\r
+               throws StandardException, IOException\r
+       {\r
+\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.ASSERT(this.page != null);\r
+               }\r
+\r
+               DynamicByteArrayOutputStream localLogBuffer = null;\r
+               if (logBuffer != null) {\r
+                       localLogBuffer = (DynamicByteArrayOutputStream) logBuffer;\r
+               } else {\r
+                       realStartColumn = -1;\r
+                       realSpaceOnPage = -1;\r
+                       localLogBuffer = t.getLogBuffer();\r
+               }\r
+               \r
+               if (isLongColumn) {\r
+                       this.startColumn = this.page.logLongColumn(doMeSlot, recordId,\r
+                               row[0], localLogBuffer);\r
+               } else {\r
+                       this.startColumn = this.page.logRow(doMeSlot, true, recordId,\r
+                               row, validColumns, localLogBuffer, this.startColumn, insertFlag,\r
+                               realStartColumn, realSpaceOnPage, overflowThreshold);\r
+               }\r
+\r
+               int optionalDataStart = localLogBuffer.getBeginPosition();\r
+               int optionalDataLength = localLogBuffer.getPosition() - optionalDataStart;\r
+\r
+               this.preparedLog = new ByteArray (localLogBuffer.getByteArray(), optionalDataStart,\r
+                       optionalDataLength);\r
+       }\r
+\r
+       /**\r
+         DEBUG: Print self.\r
+       */\r
+       public String toString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       return super.toString() +\r
+                       "Insert : " +\r
+                       " Slot=" + doMeSlot +\r
+                       " recordId=" + recordId;\r
+               }\r
+               else\r
+                       return null;\r
+       }\r
+\r
+}\r