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 / data / UpdateOperation.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/store/raw/data/UpdateOperation.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/store/raw/data/UpdateOperation.java
new file mode 100644 (file)
index 0000000..bf50da6
--- /dev/null
@@ -0,0 +1,343 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.store.raw.data.UpdateOperation\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.services.sanity.SanityManager;\r
+\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
+\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.types.DataValueDescriptor;\r
+\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.CompressedNumber;\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 the update of a particular row on a page.\r
+\r
+       <PRE>\r
+       @format_id      LOGOP_UPDATE\r
+               the formatId is written by FormatIdOutputStream when this object is\r
+               written out by writeObject\r
+       @purpose        update a record on the page\r
+       @upgrade\r
+       @disk_layout\r
+               PhysicalPageOperation   the super class\r
+               doMeSlot(CompressedInt) the slot the updated record is in\r
+               recordId(CompressedInt) the recordId of the updated record\r
+\r
+               OptionalData    The new image of the record (length included), \r
+                                               follow by the old image of the record (length included)\r
+       @end_format\r
+       </PRE>\r
+*/\r
+\r
+public final class UpdateOperation extends PhysicalPageOperation {\r
+\r
+       protected int                   doMeSlot;       // record slot - only valid during a doMe() operation\r
+       protected int                   recordId;       // record id\r
+       transient protected int nextColumn;     // next column that needs to be updated in a row.\r
+\r
+       transient protected ByteArray preparedLog;\r
+       \r
+       public UpdateOperation(\r
+    RawTransaction              t, \r
+    BasePage                    page, \r
+    int                         slot, \r
+    int                         recordId,\r
+    Object[]       row, \r
+    FormatableBitSet                     validColumns,\r
+    int                         realStartColumn, \r
+    DynamicByteArrayOutputStream      logBuffer, \r
+    int                         realSpaceOnPage, \r
+    RecordHandle                headRowHandle)\r
+               throws StandardException\r
+       {\r
+               super(page);\r
+\r
+               this.doMeSlot = slot;\r
+               this.recordId = recordId;\r
+               this.nextColumn = -1;\r
+               \r
+               // RESOLVE SRW-DJD/YYZ\r
+               try {\r
+                       writeOptionalDataToBuffer(t, (DynamicByteArrayOutputStream) logBuffer,\r
+                               row, validColumns, realStartColumn,\r
+                               realSpaceOnPage, headRowHandle);\r
+               } catch (IOException ioe) {\r
+                       throw StandardException.newException(\r
+                    SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);\r
+               }\r
+\r
+       }\r
+\r
+       /*\r
+        * Formatable methods\r
+        */\r
+\r
+       // no-arg constructor, required by Formatable \r
+       public UpdateOperation() { super(); }\r
+\r
+       public void writeExternal(ObjectOutput out) throws IOException \r
+       {\r
+               super.writeExternal(out);\r
+               CompressedNumber.writeInt(out, doMeSlot);\r
+               CompressedNumber.writeInt(out, recordId);\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
+               recordId = CompressedNumber.readInt(in);\r
+       }\r
+\r
+       /**\r
+               Return my format identifier.\r
+       */\r
+       public int getTypeFormatId() {\r
+               return StoredFormatIds.LOGOP_UPDATE;\r
+       }\r
+\r
+       /**\r
+               Return the last column of the row this operation logged\r
+       */\r
+       public int getNextStartColumn() {\r
+               return nextColumn;\r
+       }\r
+\r
+       /*\r
+        * Loggable methods\r
+        */\r
+       /**\r
+               Store the new record directly over the old record, the implementation\r
+               of storeRecord is responsible for removing any old data.\r
+\r
+               @exception StandardException Thrown by methods I call\r
+               @exception IOException Thrown by methods I call\r
+\r
+               @see BasePage#storeRecord\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, false, in);\r
+       }\r
+       \r
+\r
+       /*\r
+        * PhysicalPageOperation methods\r
+        */\r
+\r
+       /**\r
+               Store the old record directly over the new record, the implementation\r
+               of storeRecord is responsible for removing any new data.\r
+\r
+               @exception StandardException Thrown by methods I call\r
+               @exception IOException Thrown by methods I call\r
+\r
+               @see BasePage#storeRecord\r
+               @see PhysicalPageOperation#undoMe\r
+       */\r
+       public void undoMe(Transaction xact, BasePage undoPage,\r
+                                          LogInstant CLRInstant, LimitObjectInput in)\r
+                throws StandardException, IOException \r
+       {\r
+\r
+               int slot = undoPage.findRecordById(recordId, Page.FIRST_SLOT_NUMBER);\r
+\r
+               // skip the after image of the record\r
+               undoPage.skipRecord(in);\r
+\r
+               undoPage.storeRecord(CLRInstant, slot, false, in);\r
+               undoPage.setAuxObject(null);\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
+               Write out the changed colums of new record (from the row) followed by \r
+        changed columns of the old record (from the page).\r
+\r
+               @exception StandardException Thrown by methods I call\r
+               @exception IOException Thrown by methods I call\r
+       */\r
+       private void writeOptionalDataToBuffer(\r
+    RawTransaction                  t, \r
+    DynamicByteArrayOutputStream    logBuffer,\r
+    Object[]           row, \r
+    FormatableBitSet                         validColumns,\r
+    int                             realStartColumn, \r
+    int                             realSpaceOnPage, \r
+    RecordHandle                    headRowHandle)\r
+               throws StandardException, IOException\r
+       {\r
+\r
+               if (SanityManager.DEBUG) \r
+        {\r
+                       SanityManager.ASSERT(this.page != null);\r
+               }\r
+\r
+               if (realStartColumn == (-1)) \r
+        {\r
+                       logBuffer = t.getLogBuffer();\r
+               }\r
+\r
+               int optionalDataStart = logBuffer.getPosition();\r
+\r
+               if (SanityManager.DEBUG) \r
+        {\r
+\r
+            SanityManager.ASSERT(\r
+                (realStartColumn != -1 || optionalDataStart == 0),\r
+                "Buffer for writing optional data should start at position 0");\r
+        }\r
+\r
+\r
+               this.nextColumn = \r
+            this.page.logRow(\r
+                doMeSlot, false, recordId, row, validColumns,\r
+                logBuffer, 0, Page.INSERT_OVERFLOW, realStartColumn,\r
+                realSpaceOnPage, 100);\r
+\r
+               FormatableBitSet loggedColumns = validColumns;\r
+\r
+        // If this update results in moving columns off the current page to\r
+        // another page, then we must log the before image values of the columns\r
+        // being moved (deleted from this page) in addition to logging the\r
+        // columns actually being changed as part of the update.\r
+\r
+        if ((nextColumn != -1) && (validColumns != null))\r
+        {\r
+            // if nextColumn is not -1, then this must be an update which moves\r
+            // columns off of the current page.  If validColumns == null then\r
+            // we are logging all of the before image columns anyway.\r
+\r
+            // get total number of fields of the old record.\r
+                       int numberFields = page.getHeaderAtSlot(doMeSlot).getNumberFields();\r
+\r
+            // create new bit map, copying all bits that were set in original\r
+                       loggedColumns = new FormatableBitSet(validColumns);\r
+\r
+            // make sure there is room in the bit map to add the columns being\r
+            // deleted from the end of the row.\r
+            // The important thing is that endField must be at least as big as\r
+            // the number of columns in the entire record (including previous\r
+            // pages of a long row) up to the end of this page.\r
+            int endField = nextColumn + numberFields;\r
+            loggedColumns.grow(endField);\r
+            // now include all columns being deleted.\r
+            // This actually sets too many bits in this bit set but\r
+            // logRecord will just ignore the extra bits.\r
+                       for (int i = nextColumn; i < endField; i++)\r
+            {\r
+                               loggedColumns.set(i);\r
+                       }\r
+        }\r
+\r
+               // log the old version of the changed data\r
+               this.page.logRecord(\r
+            doMeSlot, BasePage.LOG_RECORD_FOR_UPDATE,\r
+            recordId, loggedColumns, logBuffer, headRowHandle);\r
+\r
+        // get length of all the optional data.\r
+               optionalDataStart = logBuffer.getBeginPosition();\r
+               int optionalDataLength = logBuffer.getPosition() - optionalDataStart;\r
+\r
+               // set the position to the beginning of the buffer\r
+               logBuffer.setPosition(optionalDataStart);\r
+\r
+               this.preparedLog = new ByteArray(\r
+            logBuffer.getByteArray(), optionalDataStart, optionalDataLength);\r
+       }\r
+\r
+       /*\r
+        * PageBasicOperation\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
+       public void restoreMe(Transaction xact, BasePage undoPage,\r
+                                          LogInstant CLRInstant, LimitObjectInput in)\r
+                throws StandardException, IOException \r
+       {\r
+               undoMe(xact, undoPage, CLRInstant, in);\r
+       }\r
+\r
+\r
+       public String toString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       return super.toString() + \r
+                       "Update " +\r
+                       " Slot=" + doMeSlot + \r
+                       " recordId=" + recordId;\r
+               }\r
+               else\r
+                       return null;\r
+       }\r
+}\r